二叉樹的三種非遞迴遍歷

2021-06-18 06:37:27 字數 1587 閱讀 6461

一.前序遍歷

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

1.遞迴實現

void

preorder1(bintree

*root)

//遞迴前序遍歷

}

2.非遞迴實現

根據前序遍歷訪問的順序,優先訪問根結點,然後再分別訪問左孩子和右孩子。即對於任一結點,其可看做是根結點,因此可以直接訪問,訪問完之後,若其左孩子不為空,按相同規則訪問它的左子樹;當訪問其左子樹時,再訪問它的右子樹。因此其處理過程如下:

對於任一結點p:

1)訪問結點p,並將結點p入棧;

2)判斷結點p的左孩子是否為空,若為空,則取棧頂結點並進行出棧操作,並將棧頂結點的右孩子置為當前的結點p,迴圈至1);若不為空,則將p的左孩子置為當前的結點p;

3)直到p為null並且棧為空,則遍歷結束。

void

preorder2(bintree

*root)

//非遞迴前序遍歷

if(!s.empty())

}

}

二.中序遍歷

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

1.遞迴實現

void

inorder1(bintree

*root)

//遞迴中序遍歷

}

2.非遞迴實現

根據中序遍歷的順序,對於任一結點,優先訪問其左孩子,而左孩子結點又可以看做一根結點,然後繼續訪問其左孩子結點,直到遇到左孩子結點為空的結點才進行訪問,然後按相同的規則訪問其右子樹。因此其處理過程如下:

對於任一結點p,

1)若其左孩子不為空,則將p入棧並將p的左孩子置為當前的p,然後對當前結點p再進行相同的處理;

2)若其左孩子為空,則取棧頂元素並進行出棧操作,訪問該棧頂結點,然後將當前的p置為棧頂結點的右孩子;

3)直到p為null並且棧為空則遍歷結束

void

inorder2(bintree

*root)

//非遞迴中序遍歷

if(!s.empty())

}

}

三.後序遍歷

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

1.遞迴實現

void

postorder1(bintree

*root)

//遞迴後序遍歷

}

2.非遞迴實現

要保證根結點在左孩子和右孩子訪問之後才能訪問,因此對於任一結點p,先將其入棧。如果p不存在左孩子和右孩子,則可以直接訪問它;或者p存在左孩子或者右孩子,但是其左孩子和右孩子都已被訪問過了,則同樣可以直接訪問該結點。若非上述兩種情況,則將p的右孩子和左孩子依次入棧,這樣就保證了每次取棧頂元素的時候,左孩子在右孩子前面被訪問,左孩子和右孩子都在根結點前面被訪問。

void

postorder3(bintree

*root)

//非遞迴後序遍歷

else

}

}

二叉樹的三種非遞迴遍歷

遞迴演算法和非遞迴演算法的轉換 可以借助棧,將二叉樹的遞迴演算法轉換為非遞迴演算法,下面以中序遍歷為例給出中序遍歷的非遞迴演算法。先掃瞄 並非訪問 根結點的所有左結點並將他們一一進棧。然後出戰乙個結點 p 顯然結點 p沒有左孩子結點或者左孩子結點均已訪問過 則訪問它。然後掃瞄該結點的有孩子結點,將其...

二叉樹的三種非遞迴遍歷

struct treenode 一 前序輸出二叉樹 void preorder treenode root p stk.top stk.pop p p right 二 中序輸出二叉樹 void midorder treenode root p stk.top cout void postorder ...

二叉樹的三種非遞迴遍歷

中序遍歷 後序遍歷 非遞迴必會用到棧吶!void preorder btnode b 如果左節點不存在 if top 1 訪問p節點,並將p節點入棧 2 如果左節點存在,則讓p指向左節點,迴圈1步驟 3 左節點不在了,則出棧一次,讓棧頂元素等於目前節點的親節點,藉此讓p指標指向這個左節點的兄弟。4 ...