資料結構筆記 二叉樹的遍歷

2022-06-06 18:03:09 字數 3449 閱讀 6189

二叉樹的遍歷,就是按照一定的規則訪問二叉樹,

將二叉樹的非線性結構轉換為二叉樹結點的乙個線性序列

假設 l, r, v 分別代表遍歷乙個結點的左子樹,右子樹,以及訪問該結點的操作

則遍歷總共有六種規則:

vlrvrl------ 前序

lvrrvl------ 中序

lrvrlv------ 後序

為了方便,以下演算法都採用先左後右的三種,先右後左同理

當樹非空時:按照順序訪問,若是l或者r則遞迴訪問,遇到v就直接訪問.

中序遍歷的遞迴演算法:

template void binarytree::inorder(bintreenode*subtree, void(*visit)(bintreenode*p))

}

前序遍歷的遞迴演算法:

template void binarytree::preorder(bintreenode*subtree, void(*visit)(bintreenode*p))

}

後序遍歷的遞迴演算法:

template void binarytree::postorder(bintreenode*subtree, void(*visit)(bintreenode*p))

}

為了把乙個遞迴過程改寫為乙個非遞迴過程需要利用乙個工作棧,記錄遍歷時的回退路徑

前序遍歷時,當前結點的訪問時機就是當前,

所以只需要在訪問左或者右的時候用棧暫存另一邊即可

第一種

初始化:p取根結點,棧變為空

迴圈: 訪問結點

預留右子樹指標在棧中

左子樹非空則進入左子樹,左子樹為空則彈出右子樹,下一次迴圈訪問的就是右子樹

template void binarytree::preorder(void(visit)(bintreenode*p))

}

另外一種方法:

初始化:根結點入棧

迴圈:  p取棧頂元素,訪問p

如果右子樹存在,右子樹進棧

如果左子樹存在,左子樹進棧

template void binarytree::preorder(void(visit)(bintreenode*p))

}

中序遍歷時,當前結點的訪問時機是左孩子為空或者左孩子訪問完了

所以棧用來存放當前結點,當左孩子為空時就是訪問的時機,

演算法描述:

初始化:棧為空,p取根結點

重複以下操作

當p不為空時,p進棧,p指向其左孩子,直到p左為空

若棧非空,出棧乙個,訪問,p指向其右孩子

直到p為空,且棧為空(do-while結構)

template void binarytree::inorder(void(*visit)(bintreenode*p))

//執行到此處,說明前乙個p的左孩子為空

//所以此時應該訪問前乙個p的父結點,即棧中最後進入的元素

if (!s.isempty())

} while (p != null || !s.isempty());

}

結束條件為棧為空且遍歷指標為空。

棧不為空,遍歷指標為空表示左子樹訪問完了,該訪問棧裡面的結點了

棧為空,但指標不為空時表示右子樹還沒訪問。

後序遍歷的乙個重要性質:當前訪問節點的時候,工作棧內的元素順序剛好是其祖先結點到它的路徑

後序遍歷的非遞迴比前序和中序複雜。

在遍歷左子樹時不能訪問根結點,還要遍歷右子樹。

右子樹遍歷完了才能訪問根結點。

所以我們要搞清楚的是上次訪問時在左子樹中還是右子樹中。

方法一(結點中增加標誌域):

即每次入棧時,要同時給進棧結點乙個標記,在訪問完左子樹時,還要把棧頂結點的標記改為右。

經過分析,訪問結點的時機就是其右孩子為空或者右孩子訪問完了的時候

總結演算法步驟:

初始化:棧為空,p取根結點

重複以下操作:

當p不為空時,進棧,標記為左,直到左孩子為空

定義乙個標記,用於判斷是否處於左子樹,賦值真

當處於左子樹且棧非空時,

取出棧頂元素,

判斷標記:

如果是左標記,將其改為右,再放進去,左子樹標記改為假,並指向其右孩子

如果是右標記,訪問

直到棧為空

template void binarytree::postorder(void(*visit)(bintreenode*p))

int continue1 = 1;

while (continue1 %% !s.isempty())

}} while (!s.isempty());

cout << endl;

}

方法二(增加輔助指標,記錄最後一次訪問的結點):

當 p非空或棧非空時:

如果p非空,則p的左孩子進棧

否則:p取棧頂元素

如果p右孩子存在且上次沒被訪問,p指向右孩子

否則:出棧

訪問p元素

記錄訪問的結點

p置空

另一種寫法:

p取根結點,last取root,根結點進棧

當棧非空時:

p取棧頂元素

如果,左右孩子都存在或者右孩子為空last為左孩子或者last為右孩子

訪問p指向結點,last設為p,s出棧

否則:如果右孩子存在,右孩子進棧

如果左孩子存在,左孩子進棧

方法三:

p取根結點,棧s為空

p進棧兩次

當棧非空時:

p取棧頂元素,s出棧

如果棧非空且p等於棧頂元素

若p右孩子存在,右孩子進棧兩次

若p左孩子存在,左孩子進棧兩次

否則:訪問p指向的結點

入隊順序即出隊順序,也就是訪問順序

入隊時一定要,先上後下,先左後右

初始化:p取根結點,根結點入佇列

當佇列非空時:

出佇列,訪問出來的元素

如果出來的元素有左孩子,則其左孩子入佇列

如果出來的元素有右孩子,則其右孩子入佇列

template void binarytree::levelorder(void(*visit)(bintreenode*p))

}

mysql 遍歷二叉樹 資料結構 二叉樹遍歷

這篇博文主要是研究二叉樹遍歷的遞迴與非遞迴演算法,有興趣的小夥伴可以了解下!二叉樹的遞迴遍歷 深度優先遍歷 先來張圖,看看各結點遍歷時的情況 二叉樹深度優先遍歷總結 分別為第一次,第二次,第三次進入某個結點 先序遍歷 先訪問根結點,然後先序遍歷左子樹,最後先序遍歷右子樹 根 左 右 中序遍歷 先中序...

資料結構 遍歷二叉樹

資料結構實驗之二叉樹二 遍歷二叉樹 time limit 1000ms memory limit 65536kb submit statistic problem description 已知二叉樹的乙個按先序遍歷輸入的字串行,如abc,de,g,f,其中,表示空結點 請建立二叉樹並按中序和後序的方...

資料結構 遍歷二叉樹

二叉樹的遍歷原理 二叉樹的遍歷是指從根節點出發,按照某種次序以此訪問二叉樹所有節點,使得每個節點被訪問一次且僅被訪問一次 二叉樹遍歷方法 1.前序遍歷 規則是若二叉樹為空,則空操作返回,否則先訪問根節點,然後前序遍歷左子樹,再前序遍歷右子樹 2.中序遍歷 規則是若樹為空,則空操作返回,否則從根節點開...