- 二叉树的遍历
- 先序遍历
遍历过程:访问根节点、先序遍历其左子树、先序遍历其右子树。
void PreOrderTraversal(BinTree BT){
if(BT){
printf("%d",BT->Data);
PreOrderTraversal(BT->Left);
PreOrderTraversal(BT->Right);
}
}
- 中序遍历
遍历过程为:中序遍历其左子树、访问根结点、中序遍历其右子树。
void InOrderTraversal(BinTree BT){
if(BT){
InOrderTraversal(BT->Left);
printf("%d",BT->Data);
InOrderTraversal(BT->Right);
}
}
- 后序遍历
遍历过程为:后序遍历其左子树、后序遍历其右子树、访问根结点。
void PostOrderTraversal(BinTree BT){
if(BT){
PostOrderTraversal(BT->Left);
PostOrderTraversal(BT->Right);
printf("%d",BT->Data);
}
}
- 先序、中序和后序遍历过程:遍历过程中经过结点的路线一样,只是访问各结点的时机不同。
- 二叉树的非递归遍历
非递归算法实现的基本思路:使用堆栈
中序遍历非递归遍历算法
- 遇到一个结点,就把它压栈,并去遍历它的左子树;
- 当左子树遍历结束后,从栈顶弹出这个结点并访问它;
- 然后按其右指针再去中序遍历该结点的右子树。
void InOrderTraversal(BinTree BT){ BinTree T=BT; Stack S=CreatStack; //创建并初始化堆栈 while(T||!IsEmpty(S)){ while(T){ //一直向左并将沿途结点压入堆栈 Push(S,T); T=T->Left; } if(!IsEmpty(S)){ T=Pop(S); //结点弹出堆栈 printf("%5d",T->Data); //(访问)打印结点 T=T->Right; //转向右结点 } } }
先序遍历的非递归遍历算法
void InOrderTraversal(BinTree BT){ BinTree T=BT; Stack S=CreatStack; //创建并初始化堆栈 while(T||!IsEmpty(S)){ while(T){ //一直向左并将沿途结点压入堆栈 printf("%5d",T->Data); //(访问)打印结点 Push(S,T); T=T->Left; } if(!IsEmpty(S)){ T=Pop(S); //结点弹出堆栈 T=T->Right; //转向右结点 } } }
后序遍历的非递归算法
void PostOrderTraversal(BinTree BT) { Stack S=CreateStack(MaxSize); BinTree pre,cur; pre=NULL; cur=NULL; Push(S,BT); while(!IsEmpty(S)) { cur=S->Data[Top]; if((cur->Left==NULL&&cur->Right==NULL)||(pre!=NULL&&(cur->Left==pre||cur->Right==pre))) { printf("%5d",cur->Data); Pop(S); pre=cur; } else { if(cur->Right!=NULL) Push(S,cur->Right); if(cur->Left!=NULL) Push(S,cur->Left); } } }
基于队列的二叉树层序遍历,核心思想是每次出队一个元素,并将此结点的左儿子和右儿子入队。
void LevelOrderTraversal(BinTree BT){ Queue Q; BinTree T; if(!BT) return; Q=CreatQueue(MaxSize); AddQ(Q,BT); while(!IsEmptyQ(Q)){ T=DeleteQ(Q); printf("%d\n",T->Data); if(T->Left) AddQ(Q,T->Left); if(T->Right) AddQ(Q,T->Right); } }