二叉樹的非遞迴遍歷

2021-10-02 09:21:00 字數 1974 閱讀 4550

前序遍歷按照「根結點-左孩子-右孩子」的順序進行訪問。

具體演算法:先遍歷左孩子,並輸出。當左孩子遍歷完後,取棧頂,找右孩子。此時迴圈還沒有結束,再遍歷它的左孩子,右孩子直至孩子全部遍歷結束。

void preorder(bitree *t)//前序遍歷的非遞迴演算法

if(s.top != 0)//當左孩子遍歷完後,取棧頂,找右孩子。此時迴圈還沒有結束,再遍歷它的左孩子,直至孩子全部遍歷結束。

}printf("\n");

}

中序遍歷按照「左孩子-根節點-右孩子」的順序進行訪問。

具體演算法:先把左孩子入棧,不著急先輸出,先把所有左孩子入棧。左孩子入棧結束,取棧頂,輸出棧頂元素,遍歷右孩子,右孩子入棧。

void inorder(bitree *t)//中序遍歷的非遞迴演算法

if(s.top != 0)//左孩子入棧結束,取棧頂,輸出棧頂元素,遍歷右孩子

}printf("\n");

}

後序遍歷

後序遍歷按照「左孩子-右孩子-根節點」的順序進行訪問。

具體演算法:對於任一結點p,將其入棧,然後沿其左子樹一直往下搜尋,直到搜尋到沒有左孩子的結點,此時該結點出現在棧頂,但是此時不能將其出棧並訪問,因此其右孩子還為被訪問。所以接下來按照相同的規則對其右子樹進行相同的處理,當訪問完其右孩子時,該結點又出現在棧頂,此時可以將其出棧並訪問。這樣就保證了正確的訪問順序。可以看出,在這個過程中,每個結點都兩次出現在棧頂,只有在第二次出現在棧頂時,才能訪問它。因此需要多設定乙個變數標識該結點是否是第一次出現在棧頂

void laorder(bitree *root)//後序遍歷的非遞迴演算法

if(s.top!=0)

else

if(temp->cishu==2)//第二次輸出並制空,防止陷入死迴圈}}

printf("\n");

}

#include #include #define null 0

#define m 100

typedef struct node

bitree;

typedef struct stack

seqstack;//定義乙個儲存樹型別位址的棧,方便遍歷的時候追蹤到樹的位址。

bitree *root;//定義乙個樹根

seqstack s;//定義棧

void setnull()//初始化棧

void push(bitree *temp)//入棧操作

bitree *pop()//取棧頂並出棧頂

int empty()//判斷空棧

bitree *create() /*先序建立二叉樹的遞迴演算法*/

return t;}

void preorder(bitree *t)//前序遍歷的非遞迴演算法

if(s.top != 0)//當左孩子遍歷完後,取棧頂,找右孩子。此時迴圈還沒有結束,再遍歷它的左孩子,直至孩子全部遍歷結束。

}printf("\n");}

void inorder(bitree *t)//中序遍歷的非遞迴演算法

if(s.top != 0)//左孩子入棧結束,取棧頂,輸出棧頂元素,遍歷右孩子

}printf("\n");}

void laorder(bitree *root)//後序遍歷的非遞迴演算法

if(s.top!=0)

else} }

}printf("\n");}

int main()

建立乙個如下圖所示的二叉樹(圖畫的不太好看)

結果如下圖:

二叉樹遍歷(遞迴 非遞迴)

二叉樹以及對二叉樹的三種遍歷 先根,中根,後根 的遞迴遍歷演算法實現,以及先根遍歷的非遞迴實現。node public class node public node left public node right public object value 遍歷訪問操作介面 public inte ce ...

二叉樹非遞迴遍歷

二叉樹非遞迴遍歷的幾個要點 1 不管前序 中序還是後序,它們的遍歷路線 或者說是回溯路線,先沿左邊一直走到盡頭,然後回溯到某節點,並跳轉到該節點的右孩子 如果有的話 然後又沿著這個有孩子的左邊一直走到盡頭 都是一樣的。2 明確每次回溯的目的。比如,前序回溯的目的是為了訪問右子樹 中序回溯的目的是為了...

非遞迴遍歷二叉樹

中序遞迴遍歷 void inordertrvdigui node pnode 然而,當樹的深度很大 比如16 時 假設為滿二叉樹 樹的節點數為 2 0 2 1 2 2 2 15 2 16 65536,遍歷整個二叉樹意味著有65536次函式呼叫,這將極大地增加程式執行時間。這時,應該採取非遞迴便利二叉...