数据结构之树的遍历

三、遍历

                              A

                      B                C

                  D      E          F     G

                H   I

/*树节点C语言描述*/

#define  M  10

typedef  struct  BitNode{

              eletype  data;/*节点的数据域*/

              Struct  BitNode  *childM;/*子树指针*/

/*二叉树节点C语言描述*/

typedef  struct  BitNode{

              eletype  data;/*节点的数据域*/

              Struct  BitNode  *lchild,*rchild;/*左右子树指针*/

              }BitNode,*BiTree;/*定义一个结构变量和一个指针型结构变量*/

(一)、树的遍历

1、树的先序遍历

/*递归*/

void  tpreorder(TNode *t,int m)

      int i;

      if(t){

             print(t->data);/*访问树的结点*/

             for(i=0;i<m;i++)

                    tpreorder(t->child[i],m);/*前序遍历各子树*/

             }

}

/*非递归*/

void  NTPreorder(TNode  *t,int  m)

{

      TNode *s[Maxlen]/*Maxlen为最大的栈空间*/

      int  top=0;  /*top为栈顶指针*/

      int i;

      if (!t)  return 0;

      s[top++]=t;  /*树根指针进栈*/

      while(top>0){

             t=s[--top];

             print  (t->data) ; /*访问树结点*/

             for(i=0;i<m;i++)

             if(t->child[i]) s[top++]=t->child[i];/*各子树根结点进栈*/

             }

      }

2、树的后序遍历

/*递归*/

void  postorder(TNode *t,int m)

      int i;

      if(t){

             for(i=0;i<m;i++)

                    postorder(t->child[i],m);/*后序遍历各子树*/

             print(t->data);/*访问树的结点*/

             }

}

/*非递归*/

3、树的中序遍历

/*递归*/

void  inorder(TNode *t,int m)

      int i;

      if(t){

             inorder(t->child[0],m);/*中序遍历各左子树*/

print(t->data);/*访问树的结点*/

for(i=1;i<m;i++)

                    inorder(t->child[i],m);/*中序遍历其他各子树*/

             }

}

/*非递归*/

(二)、二叉树先序遍历(DLR,先根遍历)

1、递归定义:首先访问根节点,然后先序遍历左子树,最后先序遍历右子树。

2、前序遍历:ABDHIECFG

3、递归算法C语言描述

int  preorder(BiTree t)

{

         if(t){

                          printf(t->data);

                          preorder(t->lchild);

‘                         preorder(t->rchild);

                }

                return 1;

    }

4、利用堆栈实现二叉树的前序遍历C语言描述

void preorderTraverse(Bitree T)      /* 先序遍历二叉树的非递归算法 
         { 
                initstack(S); 
                BitTree  p=T;
                while(!stackempty(S)||p) { 
                      if(p){
                                if(print  (p->data))  return  0;/
访问根节点*/

                    push(S,p); /*当前结点指针栈*/

                    p=p->lchild;/*当前指针指向左子树*/
                              }

             else {                      /*若栈顶指针不为0*/
                               pop(S,p);           /*
栈顶元素退栈*/
                               p=p->rchild;  /*
当前指针指向右子树*/
                              } 
                           }

            return  1;
         }

(三)、二叉树中序遍历(LDR,中根遍历)

1、递归定义:首先中序遍历左子树,然后访问根结点,最后中序遍历右子树。

2、中序遍历:HDIBEAFCG

3、递归算法C语言描述

int  inorder (Bitree T)      /* 中序遍历二叉树的递归算法 */ 
               { 
                        if (T) { 
                                  inorder (T->lchild);   /* 
访问左子树 */ 
                                   print  (T->data);          /* 
访问当前结点 */ 
                                  inorder (T->rchild);   /* 
访问右子树 */ 
                              }

        return 1;
               }

4、利用堆栈实现二叉树的中序遍历C语言描述

int   inorderTraverse(Bitree T) 
                        { 
                           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 (!print(p->data)) return  0;      /* 
访问当前结点 */ 
                                       push(S, p->rchild);   /* 
向右走一步 */ 
                              } 
                           }

return 1;
                        }

 

(四)、二叉树后序遍历(LRD,后根遍历)

1、递归定义:首先后序遍历左子树,然后后序遍历右子树,最后访问根结点。

2、次序遍历:HIDEBFGCA

3、递归算法C语言描述

         int  postorder (Bitree T)      /* 后序遍历二叉树的递归算法 */ 
                 { 
                        if (T) { 
                           postorde (T->lchild);   /* 
访问左子树 */ 
                            postorder (T->rchild);   /* 
访问右子树 */ 
                            print  (t->data);             /* 
访问当前结点 */ 
                        }

                  return 1;
                  }

4、利用堆栈实现二叉树后序遍历C语言描述

int PostOrderTraverse(Bitree  T)

             {

                int  tag[MaxSize],top=-1;

initstack(S);

Bitree  p=T;

Do{

          While(p){            /*扫描左子树,入栈*/

               Push(s,p);

               Tag[++top]=0;  /*右子树还未访问过的标志*/

               p=p->lchild;

        }

        if(top>-1)

               if(tag[top]==1)     /*左右子树已被访问过*/

                      {print(gettop(s)->data);

                      pop(s);

                      top--;

                      }

               else{

                      p=gettop(s);

                      if(top>-1){

                             p=p->rchild;        /*扫描右子树*/

                             tag[top]=1;    /*置当前结点的右子树已访问过的标志*/

                      }

               }

        }while((p!=NULL)||(top!=-1));

}

()、二叉树遍历的非递归应用一例

在以二叉链表为存储结构的二叉树中,打印数据域值为x的结点(假定结点值不相同),并打印x的所有祖先的数据域值。

typedef    struct{

        bitreptr   p;

        int    tag;  /*tag=0表示已访问了左子树,tag=1表示访问了右子树*/

}snode,s[];

int   search(bitreptr      t,datatype      x)

{    top=0;

      while((t!=NULL)&&(t->data!x)||(top!=0))

      {while((t!=null)&&(t->data!=x))

             {top++;

              s[top].p=t;s[top].tag=0;  /*结点入栈,置标志0*/

              t=t->lchild;         /*找左子树*/

      }

      if((t!=null)&&(t->data=x)) /*找到*/

             {for(i=1;i<=top;i++)

                    printf(“%d/n”,s[i].p->data;

              return(1);

else

      while((top>0&&(s[top].tag==1)) top--/*退出右子树已访问的结点*/

      if(top>0)

      {  s[top].tag=1;  /*置访问标志为1,访问右子树*/

             t=s[top];

             t=t->rchild;   

      }

}

return 0;

}     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值