国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > 数据库 > 数据库应用 > 数据结构 - 二叉树的遍历

数据结构 - 二叉树的遍历

来源:程序员人生   发布时间:2015-09-15 08:17:38 阅读次数:2672次

中序遍历2叉树

1 递归算法
算法的递归定义是:
若2叉树为空,则遍历结束;否则
⑴ 中序遍历左子树(递归调用本算法);
⑵ 访问根结点;
⑶ 中序遍历右子树(递归调用本算法)。

中序遍历的递归算法

void InorderTraverse(BTNode *T) { if (T==NULL) return; InorderTraverse(T->Lchild) ; visit(T->data) ; /* 访问根结点 */ InorderTraverse(T->Rchild) ; }

2 非递归算法(略)
设T是指向2叉树根结点的指针变量,非递归算法是:
若2叉树为空,则返回;否则,令p=T
⑴ 当p不为空,p进栈, p=p->Lchild ;
⑵ 否则(即p为空),退栈到p,访问p所指向的结点;
⑶ p=p->Rchild ,转(1);
直到栈空为止。
算法实现:

#define MAX_STACK_SIZE 50 void InorderTraverse( BTNode *T) { BTNode *Stack[MAX_STACK_SIZE ] ,*p=T ; int top=0 , bool=1 ; if (T==NULL) printf(“ Binary Tree is Empty! ”) ; else { do { while (p!=NULL) { stack[++top]=p ; p=p->Lchild ; } if (top==0) bool=0 ; else { p=stack[top] ; top-- ; visit( p->data ) ; p=p->Rchild ; } } while (bool!=0) ; } }

后序遍历2叉树

1 递归算法
算法的递归定义是:
若2叉树为空,则遍历结束;否则
⑴ 后序遍历左子树(递归调用本算法);
⑵ 后序遍历右子树(递归调用本算法) ;
⑶ 访问根结点 。

后序遍历的递归算法 void PostorderTraverse(BTNode *T) { if (T!=NULL) { PostorderTraverse(T->Lchild) ; PostorderTraverse(T->Rchild) ; visit(T->data) ; /* 访问根结点 */ } } 遍历2叉树的算法中基本操作是访问结点,因此,不管是哪一种次序的遍历,对有n个结点的2叉树,其时间复杂度均为O(n) 。

2 非递归算法(略)
在后序遍历中,根结点是最后被访问的。因此,在遍历进程中,当搜索指针指向某1根结点时,不能立即访问,而要先遍历其左子树,此时根结点进栈。当其左子树遍历完后再搜索到该根结点时,还是不能访问,还需遍历其右子树。所以,此根结点还需再次进栈,当其右子树遍历完后再退栈到到该根结点时,才能被访问。
因此,设立1个状态标志变量tag :
其次,设两个堆栈S1、S2 ,S1保存结点,S2保存结点的状态标志变量tag 。S1和S2共用1个栈顶指针。
设T是指向根结点的指针变量,非递归算法是:
若2叉树为空,则返回;否则,令p=T;
⑴ 第1次经过根结点p,不访问:
p进栈S1 , tag 赋值0,进栈S2,p=p->Lchild 。
⑵ 若p不为空,转(1),否则,取状态标志值tag :
⑶ 若tag=0:对栈S1,不访问,不出栈;修改S2栈顶元素值(tag赋值1) ,取S1栈顶元素的右子树,即p=S1[top]->Rchild ,转(1);
⑷ 若tag=1:S1退栈,访问该结点;
直到栈空为止。

算法实现: #define MAX_STACK_SIZE 50 void PostorderTraverse( BTNode *T) { BTNode *S1[MAX_STACK_SIZE ] ,*p=T ; int S2[MAX_STACK_SIZE ] , top=0 , bool=1 ; if (T==NULL) printf(“Binary Tree is Empty! ”) ; else { do { while (p!=NULL) { S1[++top]=p ; S2[top]=0 ; p=p->Lchild ; } if (top==0) bool=0 ; else if (S2[top]==0) { p=S1[top]->Rchild ; S2[top]=1 ; } else { p=S1[top] ; top-- ; visit( p->data ) ; p=NULL ; /* 使循环继续进行而不至于死循环 */ } } while (bool!=0) ; }}

层次遍历2叉树

    层次遍历2叉树,是从根结点开始遍历,按层次次序“自上而下,从左至右”访问树中的各结点。
   为保证是按层次遍历,必须设置1个队列。
   设T是指向根结点的指针变量,层次遍历非递归算法是:

若2叉树为空,则返回;否则,令p=T,p入队;
⑴ 队首元素出队到p;
⑵访问p所指向的结点;
⑶将p所指向的结点的左、右子结点顺次入队。直到队空为止。

#define MAX_NODE 50 void LevelorderTraverse( BTNode *T) { BTNode *Queue[MAX_NODE] , *p=T ; int front=0 , rear=0 ; if (p!=NULL) { Queue[++rear]=p; /* 根结点入队 */ while (front<rear) { p=Queue[++front]; visit( p->data ); if (p->Lchild!=NULL) Queue[++rear]=p; /* 左结点入队 */ if (p->Rchild!=NULL) Queue[++rear]=p; /* 左结点入队 */ } } }

2叉树遍历算法的利用

    “遍历”是2叉树最重要的基本操作,是各种其它操作的基础,2叉树的许多其它操作都可以通过遍历来实现。如建立2叉树的存储结构、求2叉树的结点数、求2叉树的深度等。

2叉树的扩充方法是:在2叉树中结点的每个空链域处增加1个扩充的结点(总是叶子结点,用方框“□”表示)。对2叉树的结点值:
◆ 是char类型:扩充结点值为“?”或“#”;
◆ 是int类型:扩充结点值为0或⑴;
下面的算法是2叉树的前序创建的递归算法,读入1棵2叉树对应的扩充2叉树的前序遍历的结点值序列。每读入1个结点值就进行分析:
◆ 若是扩充结点值:令根指针为NULL;
◆ 若是(正常)结点值:动态地为该指针分配1个结点,将该值赋给根结点,然后递归地创建根的左子树和右子树。

算法实现: #define NULLKY ‘?’ #define MAX_NODE 50 typedef struct BTNode { char data ; struct BTNode *Lchild , *Rchild ; }BTNode ; BTNode *Preorder_Create_BTree(BTNode *T) /* 建立链式2叉树,返回指向根结点的指针变量 */ { char ch ; ch=getchar() ; if (ch==NULLKY) { T=NULL; return(T) ; } else { T=(BTNode *)malloc(sizeof(BTNode)) ; T
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生