4.5二叉树的遍历
定义:二叉树的遍历是指按某种次序依次访问树中的每个结点,是得每个结点均被访问一次。
(递归)
1.先序遍历
操作过程:
@为空,什么也不做;(递归边界)
@否则,访问根结点;
@先序遍历左子树;
@先序遍历右子树。
遍历序列:A B D G C E F
void PreOrder(BiTree T){
if(T!=NULL){
printf("%c"T->data); //访问根结点
PreOrder(T->lchild); //递归遍历左子树
PreOrder(T->rchild); //递归遍历右子树
}
}
中序遍历:
操作过程:
@为空什么也不做
@否则,中序遍历左子树;
@访问根结点;
@中序遍历右子树。
遍历次序:D G B A E C F
void InOrder(BiTree T){
if(T!=NULL){
InOrder(T->lchild); //递归遍历左子树
printf("%c"T->data); //访问根结点
InOrder(T->rchild); //递归遍历右子树
}
}
后序遍历:
操作过程:
@为空,什么也不做;
@否则,后序遍历左子树;
@后序遍历右子树;
@访问根结点。
遍历次序: G D B E F C A
void PostOrder(BiTree T){
if(T!=NULL){
PostOrder(T->lchild); //递归遍历左子树
PostOrder(T->rchild); //递归遍历右子树
printf("%c"T->data); //访问根结点
}
}
非递归
二叉树的遍历:
先序遍历:
void PreOrderTraverse(BiTree b){
InitStack(S);
BiTree p =b;//工作指针p
while(p || !IsEmpty(S)){
while(p){
printf("%c",p->data); // 先序遍历结点
Push(S,p);
p=p->lchild;
}
if(!IsEmpty(S)){
p=Pop(S);
P=P->rchild;
}
}
}
中序遍历:
void InOrderTraverse(BiTree b){
InitStack(S);
BiTree p =b;//工作指针p
while(p || !IsEmpty(S)){
while(p){
Push(S,p);
p=p->lchild;
}
if(!IsEmpty(S)){
p=Pop(S);
printf("%c",p->data); //中序遍历结点
P=P->rchild;
}
}
}
后序遍历:
void PostOrderTraverse(BiTree b){
InitStack(S);
BiTree p =b,r=NULL;//工作指针p 辅助指针r
while(p || !IsEmpty(S)){
//1从根结点到最左下角得左子树都入栈
if(p){
Push(S,p);
p=p->lchild;
}
//2.返回栈顶得两种情况
else{
Get(S,p);// 取栈顶
//@右子树还未访问,而且不为空,第一次栈顶
if(p->rchild &&p->rchild!=r)
p=p->rchild;
//@右子树已经访问或者为空,接下来出栈访问结点
else{
Pop(S,p);
printf("%c",p->data);
r=p; //指向访问过的右子树得根结点
p=NULL; //使P为空从而继续访问栈顶
}
}
}
}
层序遍历:
操作:
@若为空,则什么也不做。
@否则从树得第一层开始访问,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。
void LevelOrder(BiTree b){
InitQueue(Q);
BiTree p;
EnQueue(Q,b);//队头元素进栈
while(!IsEmpty){ // 队列不空
DeQueue(Q,p); //队头元素出栈
printf("%c",p->data);
if(p->lchild!=NULL)
EnQueue(Q,p->lchild);
if(p->rchild!=NULL)
EnQueue(Q,p->rchild);
}
}