1. 熟练掌握二叉树的根前序、根中序、根后序遍历的递归和非递归的算法实现,并且能够从时间和空间复杂度的角度综合考虑递归和非递归算法的不同特点。
2. 二叉树是计算机科学中应用非常广泛的数据结构之一,通过对二叉树遍历算法的递归与非递归实现加深对二叉树的理解,并且学会用二叉树来解决实际中的简单问题。
3. 训练逻辑性的思维,通过对二叉树遍历算法问题的深入思考,加深对数据结构的认识。
4. 培养程序设计,算法分析以及调试程序的能力,为日后工作中参与项目打下基础。
(1) 实现对二叉树的根前序、根中序、根后序遍历的递归和非递归以及层序遍历的不同算法;
(2) 给出二叉树的根前序和根中序,用递归算法和非递归算法分别建立二叉树。
(3) 对于二叉树的任意两个结点,给出这两个结点的最近公共祖先。
(1)操作系统:MicrosoftWindows 10 Technical Preview x64.
(2)编译环境:Microsoft Visual Studio 2013 Ultimate.
//二叉树的数据结构
struct BinaryTree
{
char Data; //结点数据
BinaryTree *LeftChild;//左子树
BinaryTree *RightChild;//右子树
};
typedef BinaryTree *ROOT;
//实现非递归算法的工作栈
struct Stack
{
BinaryTree *Data;
Stack *Next;
Stack() :Next(NULL){}
};
typedef Stack *STACK;
//实现非递归算法的辅助栈
struct AssistStack
{
BinaryTree *NodePointer[NODENUMBERS];
int Top;
};
typedef AssistStack *ATSTACK;
//实现层次遍历的队列
struct Queue
{
int Front;
int Rear;
BinaryTree *Elements[NODENUMBERS];
};
typedef Queue *QUEUE;
/*递归前序遍历二叉树*/
void RecursionPreviousSortErgodic(ROOT &Root)
{
if (!BinaryTreeIsEmpty(Root))
{
VisitData(Root);
RecursionPreviousSortErgodic(Root->LeftChild);
RecursionPreviousSortErgodic(Root->RightChild);
}
}
/*非递归前序遍历二叉树*/
void NonRecursionPreviousSortErgodic(ROOT &Root)
{
STACK BinaryTreeStack;
BinaryTreeStack = new Stack;
StackMakeNull(BinaryTreeStack);
struct BinaryTree *Node;
Node = Root;
while (Node != NULL)
{
VisitData(Node);
if (Node->RightChild != NULL)
{
StackPush(Node->RightChild, BinaryTreeStack);
}
if (Node->LeftChild != NULL)
{
Node = Node->LeftChild; //进左子树
}
else
{
Node = StackTop(BinaryTreeStack);
StackPop(BinaryTreeStack); //做子树空,访问又子树
}
}
}
/*递归中序遍历二叉树*/
void RecursionMiddleSortErgodic(ROOT &Root)
{
if (!BinaryTreeIsEmpty(Root))
{
RecursionMiddleSortErgodic(Root->LeftChild);
VisitData(Root);
RecursionMiddleSortErgodic(Root->RightChild);
}
}
/*非递归中序遍历二叉树*/
void NonRecursionMiddleSortErgodic(ROOT &Root)
{
STACK BinaryTreeStack;
BinaryTreeStack = new Stack;
StackMakeNull(BinaryTreeStack);
struct BinaryTree *Node;
Node = Root;
while ((Node != NULL) || (!StackIsEmpty(BinaryTreeStack)))
{
while (Node != NULL)
{
StackPush(Node, BinaryTreeStack);
Node = Node->LeftChild;
}
if (!StackIsEmpty(BinaryTreeStack))
{
Node = StackTop(BinaryTreeStack);
StackPop(BinaryTreeStack);
VisitData(Node);
Node = Node->RightChild;
}
}
}
/*递归后序遍历二叉树*/
void RecursionRearSortErgodic(ROOT &Root)
{
if (!BinaryTreeIsEmpty(Root))
{
RecursionRearSortErgodic(Root->LeftChild);
RecursionRearSortErgodic(Root->RightChild);
VisitData(Root);
}
}
/*非递归后序遍历二叉树*/
void NonRecursionRearSortErgodic(ROOT &Root)
{
ROOT Node;
int Target[30];
ATSTACK BinaryTreeStack;
BinaryTreeStack = new AssistStack;
AssistStackMakeNull(BinaryTreeStack);
Node = Root;
while (Node != NULL || !AssistStackIsEmpty(BinaryTreeStack))
{
while (Node != NULL)
{
AssistStackPush(Node, BinaryTreeStack);
Target[BinaryTreeStack->Top] = -1;
Node = Node->LeftChild;
}
while (!AssistStackIsEmpty(BinaryTreeStack) && Target[BinaryTreeStack->Top] == 1)
{
Node = AssistStackTop(BinaryTreeStack);
AssistStackPop(BinaryTreeStack);
VisitData(Node);
}
if (!AssistStackIsEmpty(BinaryTreeStack))
{
Target[BinaryTreeStack->Top] = 1;
Node = AssistStackTop(BinaryTreeStack);
Node = Node->RightChild;
}
else
{
break;
}
}
}
//层次遍历二叉树
void LevelSortErgodic(ROOT &Root)
{
ROOT Node;
Node = Root;
QUEUE Q;
Q = new Queue;
Q->Front = 0;
Q->Rear = 0;
if (Root == NULL)
{
return;
}
Q->Elements[++Q->Rear] = Root;
while (Q->Front != Q->Rear)
{
Node = Q->Elements[++Q->Front];
VisitData(Node);
if (Node->LeftChild != NULL)
{
Q->Elements[++Q->Rear] = Node->LeftChild;
}
if (Node->RightChild != NULL)
{
Q->Elements[++Q->Rear] = Node->RightChild;
}
}
}
/**
*Copyright(C) 2014 HIT CS
*All rights reserved.
*Data and Struct Experiment 2
*Create by Windows 8.1 Enterprise X64
*Edit and Compiled Visual Studio 2013 Ultimate
Version 1.2
Date 10/28/2014
*/
#define _CRT_SECURE_NO_WARNINGS
#define NODENUMBERS 50
#include
#include
using namespace std;
//二叉树的数据结构
struct BinaryTree
{
char Data; //结点数据
BinaryTree *LeftChild;//左子树
BinaryTree *RightChild;//右子树
};
typedef BinaryTree *ROOT;
//实现非递归算法的工作栈
struct Stack
{
BinaryTree *Data;
Stack *Next;
Stack() :Next(NULL){}
};
typedef Stack *STACK;
//实现非递归算法的辅助栈
struct AssistStack
{
BinaryTree *NodePointer[NODENUMBERS];
int Top;
};
typedef AssistStack *ATSTACK;
//实现层次遍历的队列
struct Queue
{
int Front;
int Rear;
BinaryTree *Elements[NODENUMBERS];
};
typedef Queue *QUEUE;
//对二叉树的操作函数
bool BinaryTreeIsEmpty(ROOT &Root);
char VisitData(ROOT &Root);
//对栈操作的函数
void StackMakeNull(STACK BinaryTreeStack);
void StackPush(BinaryTree *element, STACK BinaryTreeStack);
void StackPop(STACK BinaryTreeStack);
BinaryTree *StackTop(STACK BinaryTreeStack);
bool StackIsEmpty(STACK BinaryTreeStack);
//对辅助栈的操作函数
void AssistStackMakeNull(ATSTACK AssistStack);
void AssistStackPush(BinaryTree *Element, ATSTACK AssistStack);
BinaryTree *AssistStackTop(ATSTACK AssistStack);
void AssistStackPop(ATSTACK AssistStack);
bool AssistStackIsEmpty(ATSTACK AssistStack);
//由中序和前序序列生成测试二叉树的函数
void CreatTestBinaryTree(ROOT &Root);
int SearchPosition(char *MiddleSort, char element);
void PreMidCreatBinaryTree(ROOT &Root, char *Previous, int i, char *Middle, int j, int length);
//功能函数
void MainChoiceMenu(ROOT &Root);
void GeneralListOut(ROOT &Root);
void RecursionPreviousSortErgodic(ROOT &Root); //递归前序遍历二叉树
void NonRecursionPreviousSortErgodic(ROOT &Root); //非递归前序遍历二叉树
void RecursionMiddleSortErgodic(ROOT &Root); //递归中序遍历二叉树
void NonRecursionMiddleSortErgodic(ROOT &Root); //非递归中序遍历二叉树
void RecursionRearSortErgodic(ROOT &Root); //递归后序遍历二叉树
void NonRecursionRearSortErgodic(ROOT &Root); //非递归后序遍历二叉树
void LevelSortErgodic(ROOT &Root); //层序遍历二叉树
BinaryTree* findLowestCommonAncestor(ROOT &Root, BinaryTree *a, BinaryTree *b); //寻找任意两个节点的公共祖先
BinaryTree *Search(ROOT &Root, char search);
int main()
{
ROOT Root;
MainChoiceMenu(Root);
getchar();
return 0;
}
//遍历操作选择菜单
void MainChoiceMenu(ROOT &Root)
{
int choice;
char a, b;
BinaryTree *Node1, *Node2, *result;
CreatTestBinaryTree(Root);
do
{
cout << "\n\n\t二叉树遍历操作选择系统\n------------------------------------" << endl;
cout << " 1.前序递归遍历二叉树" << endl;
cout << " 2.前序非递归遍历二叉树" << endl;
cout << " 3.中序递归遍历二叉树" << endl;
cout << " 4.中序非递归遍历二叉树" << endl;
cout << " 5.后序递归遍历二叉树" << endl;
cout << " 6.后序非递归遍历二叉树" << endl;
cout << " 7.层序遍历二叉树" << endl;
cout << " 8.递归前序和后序建立二叉树结果广义表输出" << endl;
cout << " 9.任意两个根的最近公共祖先" << endl;
cout << " 0.退出系统" << endl;
cout << " \n请选择:";
cin >> choice;
switch (choice)
{
case 0:
{
cout << "\n已退出系统\n" << "键入任意内容关闭" << endl;
getchar();
break;
}
case 1:
{
cout << "\n递归前序遍历二叉树结果:";
RecursionPreviousSortErgodic(Root);
break;
}
case 2:
{
cout << "\n非递归前序遍历二叉树结果:";
NonRecursionPreviousSortErgodic(Root);
break;
}
case 3:
{
cout << "\n递归中序遍历二叉树结果:";
RecursionMiddleSortErgodic(Root);
break;
}
case 4:
{
cout << "\n非递归中序遍历二叉树结果:";
NonRecursionMiddleSortErgodic(Root);
break;
}
case 5:
{
cout << "\n递归后序遍历二叉树结果:";
RecursionRearSortErgodic(Root);
break;
}
case 6:
{
cout << "\n非递归后序遍历二叉树结果:";
NonRecursionRearSortErgodic(Root);
break;
}
case 7:
{
cout << "\n层序遍历二叉树结果:";
LevelSortErgodic(Root);
break;
}
case 8:
{
cout << "\n递归前序和后序建立二叉树结果广义表输出结果:";
GeneralListOut(Root);
break;
}
case 9:
{
cout << "\n寻找任意两个根的最近公共祖先\n-------------------------------" << endl;;
cout << "输入两个节点(如A B):";
cin >> a >> b;
Node1 = Search(Root, a);
Node2 = Search(Root, b);
result = findLowestCommonAncestor(Root, Node1, Node2);
cout << "\n节点 " << a << " 和 " << b << " 的公共祖先节点为: " << result->Data << endl;
break;
}
default:
{
cout << "\n输入有误!" << endl;
}
}
}
while (choice != 0);
}
//将建立的二叉树用广义表输出
void GeneralListOut(ROOT &Root)
{
cout << Root->Data;
if (Root->LeftChild != NULL || Root->RightChild != NULL)
{
cout << '(';
if (Root->LeftChild != NULL)
{
GeneralListOut(Root->LeftChild);
}
cout << ',';
if (Root->RightChild)
{
GeneralListOut(Root->RightChild);
}
cout << ')';
}
}
/*递归前序遍历二叉树*/
void RecursionPreviousSortErgodic(ROOT &Root)
{
if (!BinaryTreeIsEmpty(Root))
{
VisitData(Root);
RecursionPreviousSortErgodic(Root->LeftChild);
RecursionPreviousSortErgodic(Root->RightChild);
}
}
/*非递归前序遍历二叉树*/
void NonRecursionPreviousSortErgodic(ROOT &Root)
{
STACK BinaryTreeStack;
BinaryTreeStack = new Stack;
StackMakeNull(BinaryTreeStack);
struct BinaryTree *Node;
Node = Root;
while (Node != NULL)
{
VisitData(Node);
if (Node->RightChild != NULL)
{
StackPush(Node->RightChild, BinaryTreeStack);
}
if (Node->LeftChild != NULL)
{
Node = Node->LeftChild; //进左子树
}
else
{
Node = StackTop(BinaryTreeStack);
StackPop(BinaryTreeStack); //做子树空,访问又子树
}
}
}
/*递归中序遍历二叉树*/
void RecursionMiddleSortErgodic(ROOT &Root)
{
if (!BinaryTreeIsEmpty(Root))
{
RecursionMiddleSortErgodic(Root->LeftChild);
VisitData(Root);
RecursionMiddleSortErgodic(Root->RightChild);
}
}
/*非递归中序遍历二叉树*/
void NonRecursionMiddleSortErgodic(ROOT &Root)
{
STACK BinaryTreeStack;
BinaryTreeStack = new Stack;
StackMakeNull(BinaryTreeStack);
struct BinaryTree *Node;
Node = Root;
while ((Node != NULL) || (!StackIsEmpty(BinaryTreeStack)))
{
while (Node != NULL)
{
StackPush(Node, BinaryTreeStack);
Node = Node->LeftChild;
}
if (!StackIsEmpty(BinaryTreeStack))
{
Node = StackTop(BinaryTreeStack);
StackPop(BinaryTreeStack);
VisitData(Node);
Node = Node->RightChild;
}
}
}
/*递归后序遍历二叉树*/
void RecursionRearSortErgodic(ROOT &Root)
{
if (!BinaryTreeIsEmpty(Root))
{
RecursionRearSortErgodic(Root->LeftChild);
RecursionRearSortErgodic(Root->RightChild);
VisitData(Root);
}
}
/*非递归后序遍历二叉树*/
void NonRecursionRearSortErgodic(ROOT &Root)
{
ROOT Node;
int Target[30];
ATSTACK BinaryTreeStack;
BinaryTreeStack = new AssistStack;
AssistStackMakeNull(BinaryTreeStack);
Node = Root;
while (Node != NULL || !AssistStackIsEmpty(BinaryTreeStack))
{
while (Node != NULL)
{
AssistStackPush(Node, BinaryTreeStack);
Target[BinaryTreeStack->Top] = -1;
Node = Node->LeftChild;
}
while (!AssistStackIsEmpty(BinaryTreeStack) && Target[BinaryTreeStack->Top] == 1)
{
Node = AssistStackTop(BinaryTreeStack);
AssistStackPop(BinaryTreeStack);
VisitData(Node);
}
if (!AssistStackIsEmpty(BinaryTreeStack))
{
Target[BinaryTreeStack->Top] = 1;
Node = AssistStackTop(BinaryTreeStack);
Node = Node->RightChild;
}
else
{
break;
}
}
}
//层次遍历二叉树
void LevelSortErgodic(ROOT &Root)
{
ROOT Node;
Node = Root;
QUEUE Q;
Q = new Queue;
Q->Front = 0;
Q->Rear = 0;
if (Root == NULL)
{
return;
}
Q->Elements[++Q->Rear] = Root;
while (Q->Front != Q->Rear)
{
Node = Q->Elements[++Q->Front];
VisitData(Node);
if (Node->LeftChild != NULL)
{
Q->Elements[++Q->Rear] = Node->LeftChild;
}
if (Node->RightChild != NULL)
{
Q->Elements[++Q->Rear] = Node->RightChild;
}
}
}
BinaryTree *Search(ROOT &Root, char search)
{
STACK BinaryTreeStack;
BinaryTreeStack = new Stack;
StackMakeNull(BinaryTreeStack);
struct BinaryTree *Node;
Node = Root;
while (Node->Data != search)
{
if (Node->RightChild != NULL)
{
StackPush(Node->RightChild, BinaryTreeStack);
}
if (Node->LeftChild != NULL)
{
Node = Node->LeftChild; //进左子树
}
else
{
Node = StackTop(BinaryTreeStack);
StackPop(BinaryTreeStack); //做子树空,访问又子树
}
}
return Node;
}
BinaryTree* findLowestCommonAncestor(ROOT &Root, BinaryTree *a, BinaryTree *b)
{
if (Root == NULL)
{
return NULL;
}
if (Root == a || Root == b)
{
return Root;
}
BinaryTree *left = findLowestCommonAncestor(Root->LeftChild, a, b);
BinaryTree *right = findLowestCommonAncestor(Root->RightChild, a, b);
if (left && right)
{
return Root;
}
return left ? left : right;
}
/*二叉树的操作函数*/
/*--------------------------------------------*/
bool BinaryTreeIsEmpty(ROOT &Root)
{
if (Root != NULL)
{
return false;
}
return true;
}
char VisitData(ROOT &Root)
{
cout << Root->Data << " ";
return Root->Data;
}
/*栈的操作函数*/
/*--------------------------------------------*/
//将栈置空
void StackMakeNull(STACK BinaryTreeStack)
{
BinaryTreeStack = new Stack;
BinaryTreeStack->Next = NULL;
}
//压栈
void StackPush(BinaryTree *element, STACK BinaryTreeStack)
{
STACK Node;
Node = new Stack;
Node->Data = element;
Node->Next = BinaryTreeStack->Next;
BinaryTreeStack->Next = Node;
}
//删除栈顶元素
void StackPop(STACK BinaryTreeStack)
{
STACK Node;
if (BinaryTreeStack->Next)
{
Node = BinaryTreeStack->Next;
BinaryTreeStack->Next = Node->Next;
delete Node;
}
}
//弹出栈顶元素
BinaryTree *StackTop(STACK BinaryTreeStack)
{
if (BinaryTreeStack->Next)
{
return (BinaryTreeStack->Next->Data);
}
else
{
return NULL;
}
}
//判断栈是否为空
bool StackIsEmpty(STACK BinaryTreeStack)
{
if (BinaryTreeStack->Next)
{
return false;
}
else
{
return true;
}
}
/*辅助站栈的操作函数*/
/*--------------------------------------------*/
//将辅助栈置空
void AssistStackMakeNull(ATSTACK AssistStack)
{
AssistStack->Top = -1;
}
//压栈辅助栈
void AssistStackPush(BinaryTree *Element, ATSTACK AssistStack)
{
AssistStack->NodePointer[++AssistStack->Top] = Element;
}
BinaryTree *AssistStackTop(ATSTACK AssistStack)
{
return AssistStack->NodePointer[AssistStack->Top];
}
void AssistStackPop(ATSTACK AssistStack)
{
AssistStack->Top--;
}
bool AssistStackIsEmpty(ATSTACK AssistStack)
{
if (AssistStack->Top == -1)
{
return true;
}
return false;
}
/*--用于生成测试二叉树的函数部分*/
/*--------------------------------------------*/
void CreatTestBinaryTree(ROOT &Root)
{
//char PreviousSort[11] = "ABDHLEKCFG"; //二叉树的前序序列
//char MiddleSort[11] = "HLDBEKAFCG"; //二叉树的中序序列
char PreviousSort[16] = "ABDGLEHIMCFJNK"; //二叉树的前序序列
char MiddleSort[16] = "GLDBAHEMIJNFKC"; //二叉树的中序序列
int i = 0, j = 0, length;
length = strlen(PreviousSort);
PreMidCreatBinaryTree(Root, PreviousSort, i, MiddleSort, j, length);
}
//根据中序和前序表达式利用递归生成二叉树
void PreMidCreatBinaryTree(ROOT &Root, char *Previous, int i, char *Middle, int j, int length)
{
int k;
if (length <= 0) //递归终止的条件
{
return;
}
Root = new BinaryTree;
Root->LeftChild = NULL;
Root->RightChild = NULL;
Root->Data = Previous[i];
k = SearchPosition(Middle, Previous[i]);
PreMidCreatBinaryTree(Root->LeftChild, Previous, (i+1), Middle, j, (k-j));
PreMidCreatBinaryTree(Root->RightChild, Previous, (i +(k-j)+1), Middle, (k+1), (length-1-(k-j)));
}
//查找当前根节点在中序序列中的位置
int SearchPosition(char *MiddleSort, char element)
{
int i;
for (i = 0; MiddleSort[i] != '\0'; i++)
{
if (element == MiddleSort[i])
{
break;
}
}
return i;
}