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

2022-09-08 15:09:20 字數 3128 閱讀 9036

二叉樹的遍歷

1、前序遍歷

(1)遞迴的前序遍歷

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

//前序遍歷,遞迴實現

void d_preorder(binarytreenode *proot)

}

(2)非遞迴的前序遍歷

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

因此其處理過程如下:

對於任一結點p:

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

2) 判斷結點p的左孩子是否為空

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

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

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

//前序遍歷,非遞迴實現,用棧實現

void nd_preorder(binarytreenode *proot)

else}}

}

2、中序遍歷

(1)遞迴的中序遍歷

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

//中序遍歷,遞迴實現

void d_midorder(binarytreenode *proot)

}

(2)非遞迴的中序遍歷

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

對於任一結點p,

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

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

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

//中序遍歷,非遞迴實現,用棧實現

void nd_midorder(binarytreenode *proot)

else}}

}

3、後序遍歷

(1)遞迴的後序遍歷

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

//後序遍歷,遞迴實現

void d_postorder(binarytreenode *proot)

}

(2)非遞迴的後序遍歷

後序遍歷的非遞迴實現是三種遍歷方式中最難的一種。因為在後序遍歷中,要保證左孩子和右孩子都已被訪問並且左孩子在右孩子前訪問才能訪問根結點,這就為流程的控制帶來了難題。

情況1:當前節點的左孩子以及右孩子同時為空的時候,才會將當前節點值輸出

情況2:當前乙個訪問的是當前節點的左孩子或者右孩子的時候,那麼此時也會將當前節點的值輸出

具體的思路就是上述所表述的,具體的步驟如下:

(1)初始化,將根節點入棧,將前乙個訪問的置為null;

(2)如果棧不為空,取棧頂元素作為當前節點的值,判斷當前節點是否滿足兩種輸出情況,如果滿足輸出,出棧,將當前節點的值賦給pre,即前乙個訪問節點,進行下次迴圈;如果不滿足進行步驟3

(3)如果當前節點的左孩子以及右孩子都不為空,現將右孩子入棧,再入棧左孩子;如果乙個為空,那麼入棧不為空的

(4)迴圈(2)到(3),直至棧為空的時候截止。

//後序遍歷,非遞迴實現,用棧實現

void nd_postorder(binarytreenode *proot)

else}}

}

4、二叉樹遍歷的完整**:

#include 

#include

using

namespace

std;

//二叉樹結點資料結構

struct binarytreenode

;//建立二叉樹結點

binarytreenode *creatbinarytreenode(int val)

//鏈結二叉樹節點

void connectbinarytreenode(binarytreenode *pparent, binarytreenode *pleft, binarytreenode *pright)

}//銷毀二叉樹

void destorybinarytree(binarytreenode *proot)

}//前序遍歷,遞迴實現

void d_preorder(binarytreenode *proot)

}//前序遍歷,非遞迴實現,用棧實現

void nd_preorder(binarytreenode *proot)

else}}

}//中序遍歷,遞迴實現

void d_midorder(binarytreenode *proot)

}//中序遍歷,非遞迴實現,用棧實現

void nd_midorder(binarytreenode *proot)

else}}

}//後序遍歷,遞迴實現

void d_postorder(binarytreenode *proot)

}//後序遍歷,非遞迴實現,用棧實現

void nd_postorder(binarytreenode *proot)

else}}

}int main()

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

用遞迴和非遞迴實現二叉樹的前序遍歷 中序遍歷和後序遍歷並列印出相應結果。private class treenode 在遞迴呼叫時候系統自動給我們建立棧來儲存資料,而使用非遞迴時候需要我們自己實現棧來儲存資料。遞迴實現前序遍歷public void preorder treenode root sy...

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

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

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

二叉樹的中序遍歷 二叉樹的後序遍歷 測試二叉樹的節點定義如下 節點 二叉樹的前序遍歷順序為 根左右。如下圖所示,前序遍歷順序為 1245367。遞迴 public static void preorder treenode root system.out.print root.val preorde...