三、遍历
A
B C
D E F G
H I
/*树节点C语言描述*/
#define M 10
typedef struct BitNode{
eletype data;/*节点的数据域*/
Struct BitNode *child[M];/*子树指针*/
/*二叉树节点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;
}