题目:建立一棵二叉树,要求分别用递归和非递归方法实现二叉树的先序、中序和后序遍历
班级:0101019 姓名:陈圆 学号:2010210630
一、 题目分析
1. 首先是建立一棵二叉树,定义一个结点:BiTNode,存储左右子树的指针还有根结点的信息。接着就用递归的方法建立一棵二叉树。
2. 先分析用递归方法来遍历二叉树,这个很容易实现,就是利用函数递归的方法来实现就可以了。
3. 比较困难的是二叉树非递归方法的遍历,利用栈结构的“后进先出”的特点,把树的根结点压入栈中,然后遍历左右子树,左右子树依次入栈,然后出栈来实现非递归遍历。
二、 解决问题
1. 递归遍历二叉树:
算法:
Status CreateBiTree(BiTree *T)
{ //按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树
//构造二叉链表表示的二叉树T
char ch;
scanf("%c",&ch);
if(ch == ' ') *T = NULL;
el
{
if(!(*T = (BiTNode *)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
(*T)->data = ch;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
return OK;
}//CreateBiTree
Status PreOrderTraver(BiTree T,Status (* Visit)(TElemType e))
小学生发明
{ //采用二叉链表存储结构,Visit是对数据元素操作的应用函数
//先序遍历二叉树T的递归算法,对每个数据元素调用函数Visit
if(T)
{
if(Visit(T->data))
if(PreOrderTraver(T->lchild,Visit))
if(PreOrderTraver(T->rchild,Visit)) return OK;
return ERROR;
}
el return OK;
}//PreOrderTraver
Status InOrderTraver(BiTree T,Status (* Visit)(TElemType e))
{
//后序遍历二叉树T的递归算法,对每个数据元素调用函数Visit
高原红容中尔甲 if(T)
{
if(InOrderTraver(T->lchild,Visit))
if(Visit(T->data))
if(InOrderTraver(T->rchild,Visit)) return OK;
return ERROR;
}
el return OK;
}//InOrderTraver
Status PostOrderTraver(BiTree T,Status(* Visit)(TElemType e))
{
//后序遍历二叉树T的递归算法,对每个数据元素调用函数Visit
if(T)
{
if(PostOrderTraver(T->lchild,Visit))
if(PostOrderTraver(T->rchild,Visit))
if(Visit(T->data)) return OK;
return ERROR;
}
el return OK;
}//PostOrderTraver
2. 非递归遍历二叉树:
算法:/* 先序遍历二叉树的非递归算法 */
Status PreOrderTraver(BiTree T,Status (*Visit)(TElemType e))
{
SqStack S;
逆境有利于成长 BiTree p=T;
InitStack(&S);
while(p || !StackEmpty(S)){
if(p) {Push(&S,p); Visit(p->data); p = p->lchild;}
el{
Pop(&S,&p);
p=p->rchild;
}//el
}//while
return OK;
}//PreOrderTraver
/* 中序遍历二叉树的非递归算法 */
Status InOrderTraver(BiTree T,Status (*Visit)(TElemType e))
{
SqStack S;
BiTree p;
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;
}//InOrderTraver
/* 后序遍历二叉树的非递归算法 */
Status PostOrderTraver(BiTree T,Status (*Visit)(TElemType e))
{
SqStack S;
BiTree p=T;
InitStack(&S);
while(p || !StackEmpty(S)){
while(p){
p->flag = 0;
Push(&S,p);
p = p->lchild;婴儿多大用枕头
}
while(GetTop(S,&p) && p->flag == 1){
Pop(&S,&p);
Visit(p->data);
}
if(!StackEmpty(S)){
GetTop(S,&p);
p->flag = 1;
我上大班了 p = p->rchild;
}
el break;
}//while
return OK;
}//PostOrderTraver
算法函数调用关系:鱼塘承包合同
main()
PrintElement()
InitBiTree()
PreOrderTraver()
拍身份证可以戴眼镜吗InOrderTraver()
CreateBiTree() PostOrderTraver()
主要简述下非递归遍历的算法:
先序:沿着左指针访问沿途经过的根节点,同时将右指针进栈,以便在递归访问左子树完成后能得到右子树的根节点的地址,如此重复进行,直到栈底为空;
中序: 先沿着左指针走到二叉树中最左下的结点,见沿途经过的根节点指针进栈,当左指针为空时,从栈中取出根结点访问,然后再跳到右子树上,如此重复上述步骤,直到栈底为空。
年轻干部座谈会
后序:后序遍历需要另设置一个标记,用来保护访问左右子树的现场,先访问左子树到最
左下,沿途根节点进栈,当访问左子树是,标记位0,当访问右子树是,根节点的标记就为1,当标记为1和右子树为空时,访问根节点,重复上述步骤,完成遍历。
心得体会:
非递归实现树的遍历的实现的确很费心思,尤其是后序遍历,不用标记时根本没办法完成,我就在这里困了一段时间,之后上网查资料才解决的。