原文链接:点击打开链接
摘要: 这篇帖子的代码是在上大学修数据结构的时候写的,写完就上传到CSDN提供下载了,那会比较贪心,设置的下载积分比较高。工作后慢慢习惯分享,偶然看到当时上传的简单几行代码还要积分。干脆直接把代码拿过来写成帖子也省去了路过同仁下载的麻烦。
为什么写这篇帖子
这篇帖子的代码是在上大学修数据结构的时候写的,写完就上传提供下载了,那会比较贪心,设置的下载积分比较高。工作后慢慢习惯分享,偶然看到当时上传的简单几行代码还要积分。干脆直接把代码拿过来写成帖子也省去了路过同仁下载的麻烦。
这篇帖子都写了什么
如题,这篇帖子给出了二叉树三种遍历算法的递归和非递归实现。目前,我只给出了算法的具体代码实现,具体的算法描述并没有提及(貌似也没有必要说,算法很简单)。如果有需要我后面可以把算法描述流程图补充上。
顺便提一下本文中的算法使用C描述。
具体聊聊代码
开始前的准备工作
开始前还有准备工作吗?当然有,我们需要自定义栈的数据结构和操作算法算法以及二叉树的数据结构和建树算法。
栈数据结构及操作实现
//定义堆栈结构
typedef struct SNode {
BiTree Data;
struct SNode *next;
}SNode, *LStack;
//建栈
void InitStack(LStack &s)
{
s = (LStack)malloc(sizeof(LStack));
s->next = NULL;
}
//压栈
void Push(LStack &S, BiTree c)
{
LStack p;
p = (LStack)malloc(sizeof(LStack));
p->Data = c;
p->next = S->next;
S->next = p;
}
//出栈
void Pop(LStack &S, BiTree &c)
{
LStack p;
p = (LStack)malloc(sizeof(LStack));
if (S->next != NULL)
{
p = S->next;
S->next = p->next;
c = p->Data;
}
}
二叉树数据结构及建树实现
//定义二叉树结构
typedef struct BiTNode
{
char data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
//递归按中序遍历建树,输入#号代表数空
void CreateBiTree(BiTree &T)
{
char ch;
fflush(stdin);//清除缓冲区
scanf("%c", &ch);
if (ch == '#')
{
T = NULL;
}
else
{
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
遍历算法实现
递归先序遍历二叉树
//递归先序遍历二叉树
void PreOrderTraverse(BiTree T)
{
if (T)
{
printf("%c ", T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
递归中序遍历二叉树
//递归中序遍历二叉树
void InOrderTraverse(BiTree T)
{
if (T)
{
InOrderTraverse(T->lchild);
printf("%c ", T->data);
InOrderTraverse(T->rchild);
}
}
递归后序遍历二叉树
//递归后序遍历二叉树
void HOrderTraverse(BiTree T)
{
if (T)
{
HOrderTraverse(T->lchild);
HOrderTraverse(T->rchild);
printf("%c ", T->data);
}
}
非递归先序遍历
//非递归先序遍历
void POrder(BiTree T)
{
LStack s;
InitStack(s);
while ((T != NULL) || (s->next != NULL))
{
if (T != NULL)
{
printf("%c ", T->data);
Push(s, T);
T = T->lchild;
}
else
{
Pop(s, T);//回溯至父亲节点
T = T->rchild;
}
}
}
非递归中序遍历
//非递归中序遍历
void IOrder(BiTree T)
{
LStack s;
InitStack(s);
while ((T != NULL) || (s->next != NULL))
{
while (T != NULL) // 左子树入栈
{
Push(s, T);
T = T->lchild;
}
if (s->next != NULL)
{
Pop(s, T);
printf("%c ", T->data); // 访问根结点
T = T->rchild; // 通过下一次循环实现右子树遍历
}
}
}
非递归后序遍历
//非递归后序遍历
void HOrder(BiTree T)
{
BiTree p = T, q = NULL;//q作用,记录p上次访问的节点
LStack s;
InitStack(s);
Push(s, T);//根节点压栈
while (s->next != NULL)//栈不空循环进行
{
if (p&&p != q)
{
Push(s, p);
p = p->lchild;//找最左节点
}
else
{
Pop(s, p);
if (s->next != NULL)//判断栈非空,如果栈空代表根节点已经出栈
{
if (p->rchild&&p->rchild != q)
{
Push(s, p);//将节点重新压回栈
p = p->rchild;//进入右子树
}
else
{
printf("%c ", p->data);
q = p;//防止节点多次重复进栈,陷入死循环
}
}
}
}
}
调用算法
int main()
{
BiTree T;
printf("按先序遍历递归建立二叉树:\n");
CreateBiTree(T);
printf("递归先序遍历二叉树:\n");
PreOrderTraverse(T);
printf("\n递归中序遍历二叉树:\n");
InOrderTraverse(T);
printf("\n递归后序遍历二叉树:\n");
HOrderTraverse(T);
printf("\n非递归先序遍历二叉树:\n");
POrder(T);
printf("\n非递归中序遍历二叉树:\n");
IOrder(T);
printf("\n非递归中序遍历二叉树:\n");
HOrder(T);
printf("\n");
return 0;
}
调用结果如图
结束语
以上就是二叉树三种遍历算法的递归与非递归实现的具体代码,如有不明白的地方欢迎留言交流,若帖子中有错误的地方同样欢迎留言批评指正,在此谢过路过的各位大神。
.
.
.
.
.
.
你以为这就完了?最后再声情并茂的讲一讲什么是递归。