C语言两种非递归方式实现中序遍历链表二叉树
二叉树采用二叉链表存储结构,按照先序遍历的方式创建下面这棵二叉树。然后分别用中序遍历的两种非递归算法遍历这棵二叉树。最后释放二叉树的每个结点的存储空间。提示:释放二叉树结点时要先释放左子树,然后释放右子树,最后释放根结点。这与后序遍历的顺序一致,所以应付当在后序遍历的过程中释放结点,可以使用后序遍历的递归算法。
若二叉树如图所示,则
示例1:
输入:
“abc de fg ”
将#代替空格为 abc###de##fg### ("#"表示空格)
输出:
1: cbaedgf
2: cbaedgf
代码:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define maxsize 100
typedef char elemtype;
typedef struct BiTNode
{
elemtype data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
BiTree creat_bt() //前序建二叉树
{
BiTree t;
elemtype x;
scanf("%c", &x);
if (x == ' ')
t = NULL;
else
{
t = (BiTree)malloc(sizeof(BiTNode));
t->data = x; //生成根结点
t->lchild = creat_bt(); //构造左子树
t->rchild = creat_bt(); //构造右子树
}
return t;
}
void Midorder1(BiTNode *t) //非递归遍历算法1
{
printf("1: ");
BiTNode *bt = t;
struct BiTNode *st[maxsize]; //定义指针栈
int top = 0; //置空栈
while (bt || top != 0)
{
while (bt)
{
st[top++] = bt; //根指针进栈
bt = bt->lchild; //向左走到尽头
}
if (st) //访问结点,向由一步
{
bt = st[--top];
printf("%c", bt->data);
bt = bt->rchild;
}
}
}
void Midorder2(BiTNode *t) //非递归遍历算法2
{ //采用二叉链表存储结构,中序遍历二叉树T的非递归算法
printf("2: ");
BiTNode *bt = t;
struct BiTNode *st[maxsize]; //定义指针栈
int top = 0; //置空栈
while (bt || top != 0)
{
if (bt) //根指针进栈,遍历左子树
{
st[top++] = bt;
bt = bt->lchild;
}
else //根指针退栈,访问根结点,遍历右子树
{
bt = st[--top];
printf("%c", bt->data);
bt = bt->rchild;
}
}
}
void PostOrder(BiTNode *t) //后序释放
{
if (t != NULL)
{
PostOrder(t->lchild);
PostOrder(t->rchild);
free(t);
}
}
int main()
{
BiTree bt = creat_bt(), bt1;
bt1 = bt;
Midorder1(bt);
printf("\n");
Midorder2(bt);
PostOrder(bt1);
return 0;
}
第一种非递归中序遍历伪代码
Status InOrderTraverse(BiTree T, Status (* Visit)(TElemType e)){
//采用二叉链表存储结构,中序遍历二叉树T的非递归算法
//对每个数据元素调用函数Visit
InitStack(S);
Push(S, T); //根指针进栈
while(!StackEmpty(S)){
while(GetTop(S, p) && p) Push(S, p->lchild); //向左走到尽头
Pop(S, p); //空指针退栈
if(!StackEmpty(S)) { //访问结点,向由一步
Pop(S, p);
if(!Visit(p->data)) return ERROR;
Push(S, p->rchild);
} //if
} //while
return OK;
}
第二种非递归中序遍历伪代码
Status InOrderTraverse(BiTree T, Status (* Visit)(TElemType e)){
//采用二叉链表存储结构,中序遍历二叉树T的非递归算法
//对每个数据元素调用函数Visit
InitStack(S); p = T;
while (p || !StackEmpty(S)) {
if(p){ //根指针进栈,遍历左子树
Push(S, p); p = p->lchild;
}
else{ //根指针退栈,访问根结点,遍历右子树
Pop(S, p);
if(!Visit(p->data)) return ERROR;
p = p->rchild;
} //else
} //while
return OK;
} //InOrderTraverse