同一棵二叉樹(節點值均不相同)具有唯一的先序、中序、后序序列和層次序列,但不同的二叉樹可能具有相同的先序、中序序列、后序序列和層次序列,二叉樹的構造就是根據提供的某些遍歷序列構造二叉樹的結構。
由先序序列和中序序列構造二叉樹:先序序列提供了二叉樹的根節點的信息(任何一棵二叉樹的先序序列的第一個節點為根節點),而中序序列提供了由根節點將整個序列分為左、右子樹的信息。
- 確定樹的根節點:先序遍歷的第一個節點
- 求解樹的子樹:找出根節點在中序遍歷中的位置,根左邊的是左子樹,右邊的是右子樹。
- 遞歸求解樹:將左子樹和右子樹看成一棵二叉樹,重復上面步驟


由后序序列和中序序列構造二叉樹:后序序列提供了二叉樹的根節點的信息(任何一棵二叉樹的后序序列的最后一個節點為根節點),而中序序列提供了由根節點將整個序列分為左、右子樹的信息。
- 確定樹的根節點:后序遍歷的最后一個節點
- 求解樹的子樹:找出根節點在中序遍歷中的位置,根左邊的是左子樹,右邊的是右子樹。
- 遞歸求解樹:將左子樹和右子樹看成一棵二叉樹,重復上面步驟


由層次序列和中序序列構造二叉樹:層次序列提供了二叉樹的根節點的信息(任何一棵二叉樹的層次序列的第一個節點為根節點),而中序序列提供了由根節點將整個序列分為左、右子樹的信息。
- 確定樹的根節點:層次遍歷的第一個節點
- 求解樹的子樹:找出根節點在中序遍歷中的位置,根左邊的是左子樹,右邊的是右子樹。
- 遞歸求解樹:將左子樹和右子樹看成一棵二叉樹,重復上面步驟。

森林和二叉樹的相互轉換
- 樹轉換為二叉樹

- 森林轉換為二叉樹

二叉樹轉換為樹

二叉樹轉換為森林



樹的先序遍歷與其轉換的相應的二叉樹的先序遍歷的結果序列相同
樹的后序遍歷與其轉換的二叉樹的中序遍歷的結果序列相同
森林的先序遍歷和中序遍歷與所轉換得到的二叉樹的先序遍歷和中序遍歷的結果序列相同。
假設一棵二叉樹采用二叉鏈存儲結構,設計一個算法求二叉樹的高度。
- 方式 \(1\) —采用遞歸方式「基於后序遍歷」,先計算左子樹的高度,然后計算右子樹的高度,最后比較左、右子樹的高度,返回較大的那個高度\(+1\)就是二叉樹的高度。


- 方式 \(2\) —采用層次遍歷,基本思路是訪問完每一層的所有節點之后則二叉樹的深度加 \(1\)。若根節點為空,則返回 \(0\),若根節點為非空,則第一層的節點個數肯定為 \(1\)個,當第一個節點出棧后二叉樹的深度就加 \(1\)了,然后記錄這個節點的子節點的個數,當第二層的所有節點都出完隊后,也就是第二層的節點都訪問完了,此時二叉樹的深度加\(1\),如此重復,直到遍歷完二叉樹。

 采用一個變量\(last\)記錄每層的最右節點,當訪問節點的 \(front==last\) 時,即表示這一層訪問結束,這時高度應該加\(1\)。

- 方式 \(3\)—采用二叉樹的后序遍歷非遞歸算法。根據二叉樹后序遍歷的定義,先訪問根結點的左子節點,然后訪問根結點的右子節點,最后訪問根結點。如果節點值非空,首先應該進入該節點的左子樹訪問,此時由於該節點的右子樹及根結點尚未訪問,因此必須將該節點保存起來,放入棧中,以便訪問完左子樹后,從棧中取出該節點,進行其右子樹及根結點的訪問。確切的說,當一個元素位於棧頂即將處理時,其左子樹的訪問一定已經完成,如果其右子樹尚未遍歷,接下來應該進入其右子樹訪問,而此時該棧頂元素是不能出棧的,因為其根結點還未被訪問;只有等到其右子樹也訪問完成后,該棧頂元素才能出棧。所以,后序遍歷能夠找出最長的路徑,每次節點進棧后,求出當前棧的大小,遍歷結束后返回最大的棧長度即為樹的深度。

假設二叉樹采用二叉鏈表存儲結構,設計一個算法,求非空二叉樹\(b\)的寬度(即具有節點數最多的那一層的節點個數)。
- 方式 \(1\),采用層次遍歷:在遍歷的時候記錄每個節點的所在的層次,然后求層次值最大的平台。


- 方式 \(2\): 采用層次遍歷:直接記錄每一層的節點數目,然后將每一層的節點數目和當前最大的那個比較,得出最終的寬度。


假設一棵二叉樹采用二叉鏈存儲結構,設計一個算法求二叉樹中的所有葉子節點。

假設二叉樹采用二叉鏈表存儲結構,設計一個算法把二叉樹 \(b\) 復制到 \(t\) 中。

假設二叉樹采用二叉鏈表存儲結構,設計一個算法將二叉樹的左右子樹進行交換,要求不破壞原二叉樹。

假設二叉樹采用二叉鏈表存儲結構,設計一個算法判斷兩棵二叉樹是否相等。

設計一個算法將二叉樹的順序存儲結構轉換為二叉鏈表存儲。

設計一個算法將二叉樹的二叉存儲結構轉換為順序存儲。

假設二叉樹采用二叉鏈存儲結構,設計一個算法求二叉樹中節點值為 \(x\) 的節點層數。