二叉樹的構造與算法


同一棵二叉樹(節點值均不相同)具有唯一的先序、中序、后序序列和層次序列,但不同的二叉樹可能具有相同的先序、中序序列、后序序列和層次序列,二叉樹的構造就是根據提供的某些遍歷序列構造二叉樹的結構。

  • 由先序序列和中序序列構造二叉樹:先序序列提供了二叉樹的根節點的信息(任何一棵二叉樹的先序序列的第一個節點為根節點),而中序序列提供了由根節點將整個序列分為左、右子樹的信息。

    • 確定樹的根節點:先序遍歷的第一個節點
    • 求解樹的子樹:找出根節點在中序遍歷中的位置,根左邊的是左子樹,右邊的是右子樹。
    • 遞歸求解樹:將左子樹和右子樹看成一棵二叉樹,重復上面步驟 屏幕快照 2016-08-02 下午8.45.55.png屏幕快照 2017-04-19 上午9.33.14
  • 由后序序列和中序序列構造二叉樹:后序序列提供了二叉樹的根節點的信息(任何一棵二叉樹的后序序列的最后一個節點為根節點),而中序序列提供了由根節點將整個序列分為左、右子樹的信息。

    • 確定樹的根節點:后序遍歷的最后一個節點
    • 求解樹的子樹:找出根節點在中序遍歷中的位置,根左邊的是左子樹,右邊的是右子樹。
    • 遞歸求解樹:將左子樹和右子樹看成一棵二叉樹,重復上面步驟 屏幕快照 2016-08-02 下午8.48.58.png屏幕快照 2017-04-19 上午9.33.37
  • 由層次序列和中序序列構造二叉樹:層次序列提供了二叉樹的根節點的信息(任何一棵二叉樹的層次序列的第一個節點為根節點),而中序序列提供了由根節點將整個序列分為左、右子樹的信息。

    • 確定樹的根節點:層次遍歷的第一個節點
    • 求解樹的子樹:找出根節點在中序遍歷中的位置,根左邊的是左子樹,右邊的是右子樹。
    • 遞歸求解樹:將左子樹和右子樹看成一棵二叉樹,重復上面步驟。 屏幕快照 2017-04-19 上午9.33.26

森林和二叉樹的相互轉換

  • 樹轉換為二叉樹 屏幕快照 2016-08-02 下午9.12.08.png
  • 森林轉換為二叉樹 屏幕快照 2016-08-02 下午9.16.06.png
  • 二叉樹轉換為樹
    屏幕快照 2016-08-02 下午9.22.06.png

  • 二叉樹轉換為森林
    屏幕快照 2016-08-02 下午9.26.57.png
    屏幕快照 2016-08-03 上午9.13.19.png
    屏幕快照 2016-08-03 上午9.12.34.png

  • 樹的先序遍歷與其轉換的相應的二叉樹的先序遍歷的結果序列相同

  • 樹的后序遍歷與其轉換的二叉樹的中序遍歷的結果序列相同

  • 森林的先序遍歷和中序遍歷與所轉換得到的二叉樹的先序遍歷和中序遍歷的結果序列相同。

假設一棵二叉樹采用二叉鏈存儲結構,設計一個算法求二叉樹的高度。

  • 方式 \(1\) —采用遞歸方式「基於后序遍歷」,先計算左子樹的高度,然后計算右子樹的高度,最后比較左、右子樹的高度,返回較大的那個高度\(+1\)就是二叉樹的高度。 屏幕快照 2016-08-01 下午10.53.08.png屏幕快照 2016-08-02 下午7.15.07.png
  • 方式 \(2\) —采用層次遍歷,基本思路是訪問完每一層的所有節點之后則二叉樹的深度加 \(1\)。若根節點為空,則返回 \(0\),若根節點為非空,則第一層的節點個數肯定為 \(1\)個,當第一個節點出棧后二叉樹的深度就加 \(1\)了,然后記錄這個節點的子節點的個數,當第二層的所有節點都出完隊后,也就是第二層的節點都訪問完了,此時二叉樹的深度加\(1\),如此重復,直到遍歷完二叉樹。 屏幕快照 2016-08-03 上午9.24.53.png屏幕快照 2016-08-03 上午11.15.43.png 采用一個變量\(last\)記錄每層的最右節點,當訪問節點的 \(front==last\) 時,即表示這一層訪問結束,這時高度應該加\(1\)。 屏幕快照 2016-08-02 下午7.30.50.png
  • 方式 \(3\)—采用二叉樹的后序遍歷非遞歸算法。根據二叉樹后序遍歷的定義,先訪問根結點的左子節點,然后訪問根結點的右子節點,最后訪問根結點。如果節點值非空,首先應該進入該節點的左子樹訪問,此時由於該節點的右子樹及根結點尚未訪問,因此必須將該節點保存起來,放入棧中,以便訪問完左子樹后,從棧中取出該節點,進行其右子樹及根結點的訪問。確切的說,當一個元素位於棧頂即將處理時,其左子樹的訪問一定已經完成,如果其右子樹尚未遍歷,接下來應該進入其右子樹訪問,而此時該棧頂元素是不能出棧的,因為其根結點還未被訪問;只有等到其右子樹也訪問完成后,該棧頂元素才能出棧。所以,后序遍歷能夠找出最長的路徑,每次節點進棧后,求出當前棧的大小,遍歷結束后返回最大的棧長度即為樹的深度屏幕快照 2016-08-03 上午11.12.55.png

假設二叉樹采用二叉鏈表存儲結構,設計一個算法,求非空二叉樹\(b\)的寬度(即具有節點數最多的那一層的節點個數)。

  • 方式 \(1\),采用層次遍歷:在遍歷的時候記錄每個節點的所在的層次,然后求層次值最大的平台。 屏幕快照 2016-08-02 上午11.25.53.png屏幕快照 2016-08-02 上午11.26.18.png
  • 方式 \(2\): 采用層次遍歷:直接記錄每一層的節點數目,然后將每一層的節點數目和當前最大的那個比較,得出最終的寬度。 屏幕快照 2016-08-02 下午5.02.25.png屏幕快照 2016-08-02 下午5.03.34.png

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

屏幕快照 2016-08-01 下午11.06.27.png

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

屏幕快照 2016-08-02 上午9.23.18.png

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

屏幕快照 2016-08-02 上午9.23.54.png

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

屏幕快照 2016-08-02 上午9.32.22.png

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

屏幕快照 2016-08-02 上午9.56.05.png

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

屏幕快照 2016-08-02 上午10.04.19.png

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

屏幕快照 2016-08-02 上午10.19.37.png
屏幕快照 2016-08-02 上午10.36.30.png
屏幕快照 2016-08-02 上午10.36.54.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM