1. 程式人生 > >後序非遞迴遍歷二叉樹

後序非遞迴遍歷二叉樹

非遞迴後序遍歷演算法思想

  後序遍歷的非遞迴演算法中節點的進棧次數是兩個,即每個節點都要進棧兩次,第二次退棧的時候才訪問節點。
  第一次進棧時,在遍歷左子樹的過程中將”根”節點進棧,待左子樹訪問完後,回溯的節點退棧,即退出這個”根”節點,但不能立即訪問,只能藉助於這個”根”去找該”根”的右子樹,並遍歷這棵右子樹,直到該右子樹全部遍歷以後,再退出該”根”節點,並訪問它。
  所以為了記錄節點是第一次還是第二次進棧,就在堆疊資料元素的結構中增加一個數據項:進棧標誌。
  (1)當節點非空時或堆疊非空時,執行(2),否則結束演算法;
  (2)當節點指標非空時,節點的進棧標誌設為false,節點指標及進棧標誌進棧,然後將節點指向進棧節點的左子樹的根,重複(2),知道指標為空(最後一個進棧的是最左子樹),節點指標為空時,轉(3);
  (3)堆疊非空時,從堆疊中退出一個節點的指標。如果退出的節點的進棧標誌為true,說明該節點是第二次退棧,訪問該接點,並將指標強制設為空,準備下一次退棧,並轉(3),如果進棧標誌為false,說明該節點是第一次退棧,將進棧標誌設為true,然後將該節點指標及進棧標誌進棧,再將指標指向它的右子樹,轉(1)。

程式碼實現

#include<stdio.h>  
#include<stdlib.h>  

typedef char EType;   

struct BinaryTreeNode  
{  
    EType data;  
    struct BinaryTreeNode *LChild;  
    struct BinaryTreeNode *RChild;  
};  
typedef BinaryTreeNode BinaryTree;  

typedef struct SType  
{  
    BinaryTreeNode *ptr;  
    bool
status;//進棧標誌 }SType; typedef struct Stack { SType *element; int top; int MaxSize; }Stack; void CreatStack(Stack &S,int MaxStackSize); bool IsEmpty(Stack &S); bool IsFull(Stack &S); bool GetTop(Stack &S,SType &result); bool Pop(Stack &S,SType &result); bool
Push(Stack &S,SType &x); void CreatBiTree(BinaryTreeNode **BT); void PostOrderNoRecursive(BinaryTreeNode *BT); int main() { BinaryTreeNode *BT = NULL; CreatBiTree(&BT); printf("後序遍歷二叉樹非遞迴演算法輸出為:"); PostOrderNoRecursive(BT); printf("\n"); return 0; } void CreatStack(Stack &S,int MaxStackSize) { S.MaxSize = MaxStackSize; S.element = new SType[S.MaxSize]; S.top = -1; } bool IsEmpty(Stack &S) { if(S.top == -1) return true; return false; } bool IsFull(Stack &S) { if(S.top >= S.MaxSize-1) return true; return false; } bool GetTop(Stack &S,SType &result) { if(IsEmpty(S)) return false; result = S.element[S.top]; return true; } bool Pop(Stack &S,SType &result) { if(IsEmpty(S)) return false; result = S.element[S.top]; S.top--; return true; } bool Push(Stack &S,SType &x) { if(IsFull(S)) return false; S.top++; S.element[S.top] = x; return true; } void CreatBiTree(BinaryTreeNode **BT) { EType tem; scanf("%c",&tem); if(' ' == tem) { *BT = NULL; } else { *BT = new BinaryTreeNode; (*BT)->data = tem; CreatBiTree(&(*BT)->LChild); CreatBiTree(&(*BT)->RChild); } } void PostOrderNoRecursive(BinaryTreeNode *BT) { Stack S; SType temp; BinaryTreeNode *p = BT; int MaxStackSize = 50; CreatStack(S,MaxStackSize); while(p || !IsEmpty(S)) { if(p)//找最左子樹 { temp.status = false;//設定該節點是第一次進棧 temp.ptr = p; Push(S,temp); p = p->LChild; } else { if(!IsEmpty(S)) /*該判斷多餘?*/ { Pop(S,temp); p = temp.ptr; if(temp.status)//若該節點是第二次退棧,就訪問,並設定p=0繼續退棧 { printf("%c\t",p->data); p = NULL; } else { temp.status = true;//設定該節點是第二次進棧 Push(S,temp); p = p->RChild;//遍歷該節點的右子樹 } } } } }