二叉樹的四種遍歷的遞迴和非遞迴的實現

2021-07-12 07:30:53 字數 1919 閱讀 7538

二叉樹的三種遍歷為:前序遍歷,中序遍歷和後序遍歷。

遍歷的實現可分為遞迴和非遞迴。遞迴法與二叉樹的定義相似,非遞迴法採用棧去模擬實現。

一、前序遍歷的次序為:根結點——左結點——右結點。

遞迴法實現:

//前序遍歷的遞迴實現

void preorder1(binarytreenode* proot)

非遞迴的實現:

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

對於任一結點p:

step 1:訪問結點p,並將結點p入棧。

step 2:判斷結點p的左孩子是否為空。若為空,則取棧頂結點並出棧,將棧頂元素的右孩子設為當前的結點p,迴圈至step 1。

若不為空,則將p的左孩子設為當前結點p。

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

//前序遍歷的非遞迴遍歷

void preorder2(binarytreenode* proot)

if(!s.empty())

}}

二、中序遍歷的次序為:左結點——根結點——右結點

遞迴法:

//中序遍歷的遞迴法

void inorder1(binarytreenode* proot)

非遞迴法:

根據中序遍歷的順序,對於任一結點,先訪問其左孩子。而左孩子又可以看做乙個根結點,然後繼續訪問左孩子,直到遇到的左孩子結點為空,則停止訪問。然後訪問右孩子。

處理過程如下:

對於任一結點p:

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

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

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

//中序遍歷的非遞迴法

void inorder(binarytreenode* proot)

if(!s.empty())

}}

三、後序遍歷

遞迴法:左結點——右結點——根結點。

//後序遍歷的遞迴法

void postorder1(binarytreenode* proot)

非遞迴遍歷:要保證根結點在左孩子和右孩子訪問之後才能訪問。因此對於任一結點p,先將其入棧。

若p不存在左孩子和右孩子,則可以直接訪問它。或者p存在左孩子或者右孩子,但是左孩子和右孩子都已經被訪問過了,則可以直接訪問該結點。

若非上述兩種情況,則將右孩子和左孩子依次入棧。這樣可以保證每次取棧頂元素時,左孩子在右孩子前面被訪問,根結點在左孩子和右孩子訪問之後被訪問。

//後序遍歷的非遞迴法

void postorder(binarytreenode* proot)

else

}}

四、層次遍歷(劍指offer上有涉及)

題目:從上到下列印二叉樹的每個節點,同層的節點按照從左向右列印。

解析:即分層遍歷二叉樹。利用廣度優先遍歷的思想,遍歷樹或者有向圖,都可在佇列中完成。

step1:把起始節點放入佇列。

step2:每次從隊頭取出節點,遍歷(輸出)。接下來,把從該節點能到達的節點(子樹或者其他)都依次放入佇列。

重複step2,直到佇列中的節點為空。

void printfromtoptobottom(binarytreenode* proot)

}

二叉樹的四種遍歷(遞迴與非遞迴)

先序遍歷根節點,再遍歷左子樹,再遍歷右子樹。後序遍歷先遍歷左子樹,再遍歷右子樹,再遍歷根節點。先序遍歷遞迴實現 public static void preorderbyrecursion treenode root 先序遍歷的非遞迴實現 非遞迴實現需要借助棧這樣乙個資料結構,實際上遞迴實現也是依靠...

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

二 叉樹是一種非常重要的資料結構,很多其它資料結構都是基於二叉樹的基礎演變而來的。對於二叉樹,有前序 中序以及後序三種遍歷方法。因為樹的定義本身就是 遞迴定義,因此採用遞迴的方法去實現樹的三種遍歷不僅容易理解而且 很簡潔。而對於樹的遍歷若採用非遞迴的方法,就要採用棧去模擬實現。在三種遍歷中,前序和中...

二叉樹的遞迴遍歷和非遞迴遍歷

二叉樹是一種基本的資料結構,在程式設計師面試中經常會被考察。其中按一定順序遍歷所有節點是最基本的操作,很多知名的面試題目,例如求二叉樹的深度 求出和為某一值的路徑等等,本質上都是遍歷的變種。本文試圖從遞迴和非遞迴的角度來考察一下遍歷的演算法。遍歷定義 在二叉樹中,每乙個節點都有左右兩個子節點 子節點...