層次遍歷利用隊列,很容易實現,先根節點入隊,出隊,每次出隊檢查左右子節點是否爲空,非空則入隊,如此往復直至隊空,代碼如下
//層次遍歷輸出二叉樹
void levelOrder(BiTree biT){
printf("層次遍歷結果:\n");
initQueue(&sqQueue);
BiTree p;
enQueue(&sqQueue,biT);
while(!isEmpty(sqQueue)){
deQueue(&sqQueue,&p);
printf("%d ",p->data);
if(p->lchild!=NULL)
enQueue(&sqQueue,p->lchild);
if(p->rchild!=NULL)
enQueue(&sqQueue,p->rchild);
}
}
前序遍歷非遞歸依靠棧實現,相對來說比較簡單,先來用手寫模擬一下基本就能知道怎麼寫了
據此可得如下代碼
void preOrder_stack(BiTree T){
printf("\n非遞歸先序遍歷結果:\n");
initStack(&sqStack);
BiTree p=T;
push(&sqStack,p);
while(!stackEmpty(sqStack)){
pop(&sqStack,&p);
printf("%d ",p->data);
if(p->rchild){
push(&sqStack,p->rchild);
}
if(p->lchild){
push(&sqStack,p->lchild);
}
}
}
中序遍歷比前序要稍微複雜些,我也先用手寫理出思路
代碼寫的和書上的一比。。。感覺麻煩了好多,但畢竟是自己理的思路不容易忘,所以還是貼自己的
void inOrder_stack(BiTree T){
printf("\n非遞歸中序遍歷結果:\n");
initStack(&sqStack);
BiTree p=T,l;//l用於保存上次的輸出
push(&sqStack,p);
while(!stackEmpty(sqStack)){
getTop(&sqStack,&p);
if(p->lchild!=NULL&&p->lchild!=l){
push(&sqStack,p->lchild);
}
else {
pop(&sqStack,&l);
printf("%d ",l->data);
if(l->rchild!=NULL){
push(&sqStack,l->rchild);
}
else if(l->rchild==NULL){
if(!stackEmpty(sqStack)){
pop(&sqStack,&l);
printf("%d ",l->data);
if(l->rchild!=NULL){
push(&sqStack,l->rchild);
}
}
}
}
}
}
後序應該是三種裏面最複雜的一個了,如下
代碼如下
void postOrder_stack(BiTree T){
printf("\n非遞歸後序遍歷結果:\n");
initStack(&sqStack);
BiTree p=T,l;//l用於保存最近一次pop出的節點
push(&sqStack,p);
while(!stackEmpty(sqStack)){
getTop(&sqStack,&p);
if(p->lchild!=NULL){
if(l!=p->lchild&&l!=p->rchild){//若左右子節點均未被訪問過,推入左子節點
push(&sqStack,p->lchild);
}
else if(l==p->lchild){//左子節點訪問過,若右子節點非空,則壓入右子節點,否則,輸出
if(p->rchild!=NULL)
push(&sqStack,p->rchild);
else if(p->rchild==NULL){
pop(&sqStack,&l);
printf("%d ",l->data);
}
}
else if(l==p->rchild){//右子節點訪問過,則左右子節點均訪問完,彈出當前節點
pop(&sqStack,&l);
printf("%d ",l->data);
}
}
else if(p->lchild==NULL){
if(p->rchild==NULL){//左右子節點爲空,則直接彈出,彈出節點保存在l中
pop(&sqStack,&l);
printf("%d ",l->data);
}
else if(p->rchild!=NULL){
if(l==p->rchild){//右子節點訪問過,則左右子節點均訪問完,彈出當前節點
pop(&sqStack,&l);
printf("%d ",l->data);
}else if(l!=p->rchild){
push(&sqStack,p->rchild);
}
}
}
}
}
由第一張圖可以看出,每次輸出時,棧頂自上而下保存的是該節點到根節點的路徑,這是個很有用的特性,所以後序遍歷雖然複雜些但也得掌握。