二叉树遍历算法总结
本文根据《数据结构与算法》(C语言版)(第三版) 整理。
void PreOrderTraverse(BiTree BT)
{
if(BT)
{
printf("%c",BT->data); //访问根结点
PreOrderTraverse(BT->lchild); //前序遍历左子树
PreOrderTraverse(BT->rchild); //前序遍历右子树
}
}
void PreOrderNoRec(BiTree BT)
{
stack S;
BiTree p=BT->root;
while((NULL!=p)||!StackEmpty(S))
{
if(NULL!=p)
{
printf("%c",p->data);
Push(S,p);
p=p->lchild;
}
else
{
p=Top(S);
Pop(S);
p=p->rchild;
}
}
}
void PreOrder(pBinTreeNode pbnode)
{
pBinTreeNode stack[100];
pBinTreeNode p;
int top;
top=0;
p=pbnode;
do
{
while(p!=NULL)
{
printf("%d\n",p->data); //访问结点p
top=top+1;
stack[top]=p;
p=p->llink; //继续搜索结点p的左子树
}
if(top!=0)
{
p=stack[top];
top=top-1;
p=p->rlink; //继续搜索结点p的右子树
}
}while((top!=0)||(p!=NULL));
}
void InOrderTraverse(BiTree BT)
{
if(BT)
{
InOrderTraverse(BT->lchild); //中序遍历左子树
printf("%c",BT->data); //访问根结点
InOrderTraverse(BT->rchild); //中序遍历右子树
}
}
void IneOrderNoRec(BiTree BT)
{
stack S;
BiTree p=BT->root;
while((NULL!=p)||!StackEmpty(S))
{
if(NULL!=p)
{
Push(S,p);
p=p->lchild;
}
else
{
p=Top(S);
Pop(S);
printf("%c",p->data);
p=p->rchild;
}
}
} void InOrder(pBinTreeNode pbnode)
{
pBinTreeNode stack[100];
pBinTreeNode p;
int top;
top=0;
p=pbnode;
do
{
while(p!=NULL)
{
top=top+1;
stack[top]=p; //结点p进栈
p=p->llink; //继续搜索结点p的左子树
}
if(top!=0)
{
p=stack[top]; //结点p出栈
top=top-1;
printf("%d\n",p->data); //访问结点p
p=p->rlink; //继续搜索结点p的右子树
}
}while((top!=0)||(p!=NULL));
} void PostOrderTraverse(BiTree BT)
{
if(BT)
{
PostOrderTraverse(BT->lchild); //后序遍历左子树
PostOrderTraverse(BT->rchild); //后序遍历右子树
printf("%c",BT->data); //访问根结点
}
}
void PostOrderNoRec(BiTree BT)
{
stack S;
stack tag;
BiTree p=BT->root;
while((NULL!=p)||!StackEmpty(S))
{
while(NULL!=p)
{
Push(S,p);
Push(tag,0);
p=p->lchild;
}
if(!StackEmpty(S))
{
if(Pop(tag)==1)
{
p=Top(S);
Pop(S);
printf("%c",p->data);
Pop(tag); //栈tag要与栈S同步
}
else
{
p=Top(S);
if(!StackEmpty(S))
{
p=p->rchild;
Pop(tag);
Push(tag,1);
}
}
}
}
}
void PosOrder(pBinTreeNode pbnode)
{
pBinTreeNode stack[100]; //结点的指针栈
int count[100]; //记录结点进栈次数的数组
pBinTreeNode p;
int top;
top=0;
p=pbnode;
do
{
while(p!=NULL)
{
top=top+1;
stack[top]=p; //结点p首次进栈
count[top]=0;
p=p->llink; //继续搜索结点p的左子树
}
p=stack[top]; //结点p出栈
top=top-1;
if(count[top+1]==0)
{
top=top+1;
stack[top]=p; //结点p首次进栈
count[top]=1;
p=p->rlink; //继续搜索结点p的右子树
}
else
{
printf("%d\n",p->data); //访问结点p
p=NULL;
}
}while((top>0));
} typedef struct node
{
DataType data;
struct node *lchild, *rchild; //左、右孩子指针
int ltag, rtag; //左、右线索
}TBinTNode; //结点类型
typedef TBinTNode *TBinTree; 在线索化二叉树中,一个结点是叶子结点的充分必要条件是其左、右标志均为1. void InOrderThreading(TBinTree p)
{
if(p)
{
InOrderThreading(p->lchild); //左子树线索化
if(p->lchild)
p->ltag=0;
else
p->ltag=1;
if(p->rchild)
p->rtag=0;
else
p->rtag=1;
if(*(pre)) //若*p的前驱*pre存在
{
if(pre->rtag==1)
pre->rchild=p;
if(p->ltag==1)
p->lchild=pre;
}
pre=p; //另pre是下一访问结点的中序前驱
InOrderThreading(p->rchild); //右子树线索化
}
} TBinTNode *InOrderSuc(BiThrTree p)
{
TBinTNode *q;
if(p->rtag==1) //第①情况
return p->rchild;
else //第②情况
{
q=p->rchild;
while(q->ltag==0)
q=q->lchild;
return q;
}
} TBinTNode *InOrderPre(BiThrTree p)
{
TBinTNode *q;
if(p->ltag==1)
return p->lchild;
else
{
q=p->lchild; //从*p的左孩子开始查找
while(q->rtag==0)
q=q->rchild;
return q;
}
} void TraversInOrderThrTree(BiThrTree p)
{
if(p)
{
while(p->ltag==0)
p=p->lchild;
while(p)
{
printf("%c",p->data);
p=InOrderSuc(p);
}
}
}
原文:http://blog.csdn.net/wp1603710463/article/details/50937743