樹--《大話數據結構》

一、樹的定義

樹是由n(n>=1)個有限結點組成一個具有層次關係的集合,根朝上,葉朝下

樹具有以下的特點:
① 每個結點有零個或多個子結點;沒有父結點的結點稱爲根結點;
② 每一個非根結點有且只有一個父結點;
③ 除了根結點外,每個子結點可以分爲多個不相交的子樹。

注意:
① n > 0時根結點是唯一的,不可能存在多個根節點;
② 由子結點構成的子樹個數沒有限制,但它們一定是互不相交的。
樹結構示意圖

二、樹的相關概念

  1. 空樹: 樹結點的個數(n≥0),當n=0時,稱爲空樹;
  2. 結點間的關係:
    ① 結點的子樹的根稱爲該結點的孩子(Child),相應地,該結點稱爲孩子的雙親(Parent)
    ② 同一個雙親的孩子之間互稱兄弟
    ③ 結點的祖先是從根到該結點所經分支上的所有結點;
    ④ 反之,以某結點爲根的子樹中的任一結點都稱爲該結點的子孫
    結點間的關係
  3. 結點的分類:
    結點的度(Degree): 結點擁有的子樹數;
    樹的度: 樹內各結點的度的最大值;
    葉結點: 度爲0的結點,也稱爲終端結點,無孩子,在樹中可以存在多個;
    分支結點: 度不爲0的結點,也稱爲非終端結點
    內部結點: 樹中除根結點之外的分支結點,一個雙親多個孩子;
    結點分類
  4. 結點的層次: 由結點位置,從根開始定義,根爲第一層,往下遞增(同層的結點互爲堂兄弟);
    樹的深度(Depth): 樹中結點的最大層次,也稱爲高度
    結點豎直概念

三、樹的存儲結構

  • 雙親表示法:
    每個結點分別由一個數據域和一個指針域構成。數據域存儲結點的數據信息,指針域儲存雙親的地址。
    注意: 因爲根結點沒有雙親,故約定其指針域爲NULL。

  • 孩子表示法:
    每個結點分別由一個數據域和多個指針域構成。指針域指向每一棵子樹的根結點。也稱爲多重鏈表表示法
    注意: 因爲不同結點的孩子個數可能有差異,故需要設計方案解決:
    ① 按樹的度,也就是樹中各個結點度的最大值,指定指針域的個數;(浪費內存)
    ② 每個結點指針域的個數等於該結點的度。增添一個專門位置,存儲結點指針域的個數;(維護麻煩)
    ③ 將每個結點的孩子排列起來,以單鏈表作存儲結構(葉子結點則此鏈表爲空)。然後將這些鏈表的頭指針,組成一個線性表存儲。

  • 孩子兄弟表示法:
    每個結點分別由一個數據域和兩個指針域構成。指針域指向該結點的第一個孩子和右兄弟。該方法本質上等價於將任意一個複雜的樹,轉換成二叉樹結構
    注意: 若某結點沒有孩子或右兄弟,將對應的指針域設定爲NULL。

四、特殊樹——二叉樹

4.1 二叉樹的定義

二叉樹是n個結點的有限集合,該集合或者爲空集(稱爲空二叉樹),或者由一個根結點和兩棵互不相交的(分別稱爲根結點的左子樹、右子樹)二叉樹組成。

二叉樹具有以下特點:
① 每個結點最多隻有兩棵子樹,所以二叉樹中的結點度取值只能爲三個值——0、1、2
② 左子樹和右子樹是有順序的,不能任意顛倒;
③ 即使樹中某結點只有一棵子樹,也要區分其是左子樹還是右子樹。

二叉樹具有五種基本形態:
① 空二叉樹;
② 只有一個根結點;
③ 根結點只有左子樹;
④ 根結點只有右子樹;
⑤ 根結點既有左子樹又有右子樹。

4.2 二叉樹的存儲結構

  • 順序存儲結構: 用一維數組存儲二叉樹中的結點,並且結點的存儲位置(數組的下標),需要體現結點之間的邏輯關係(雙親與孩子、兄弟等)。(維護麻煩、浪費內存,一般不會使用)
    存儲時,將目標二叉樹看作完全二叉樹,對各結點進行層序編號。其編號,就是在數組中存儲時的下標。若某個編號對應的結點不存在,在數組中存儲特殊標誌值表示。
  • 二叉鏈表: 每個結點分別由一個數據域和兩個指針域構成。指針域分別指向存放左、右孩子的地址。如下圖:
    二叉鏈表

4.3 二叉樹的性質

  1. 在二叉樹的第i層上至多2(i - 1) 個結點(i ≥ 1).;
  2. 深度爲k的二叉樹至多2k - 1個結點(k ≥ 1) ;
  3. 對任何一棵二叉樹,若終端結點數爲a,度爲2的結點數爲b,則a = b + 1
  4. 具有n個結點的完全二叉樹的深度爲 [log2n] + 1([x]表示不大於x的最大整數);
  5. 如果對一棵有n個結點的完全二叉樹(其深度爲[log2n] + 1)的結點按層序從上至下、從左至右編號,對任一結點i(1 ≤ i ≤ n)有:
    ① 若i = 1,則結點i是二叉樹的根,無雙親;若i > 1,其雙親是結點 [i / 2]
    ② 若2i > n,則結點i無左孩子(結點i爲葉子結點);否則,其左孩子是結點2i
    ③ 若2i + 1 > n,則結點i無右孩子;否則,其右孩子是結點2i + 1

4.4 特殊形式二叉樹

4.4.1 斜樹:

所有結點都只有左子樹的二叉樹叫左斜樹。所有結點都只有右子樹的二叉樹叫右斜樹。這兩者統稱爲斜樹。

4.4.2 滿二叉樹:

在一棵二叉樹中,若所有分支結點都存在左子樹和右子樹,並且所有葉子都在同一層上,這樣的二叉樹稱爲滿二叉樹。

滿二叉樹具有以下特點:
① 葉子只能出現在最下一層,出現在其它層就不可能達到平衡;
② 非葉子結點的度一定是2;
③ 在同樣深度的二叉樹中,滿二叉樹的結點個數最多,葉子樹最多。
滿二叉樹

4.4.3 完全二叉樹:

對一個二叉樹的結點按層次從上至下、從左至右編號。如果每個編號,與等深度的滿二叉樹相同位置的結點完全一致。則稱該樹爲完全二叉樹。

完全二叉樹具有以下特點:
① 葉子結點只能出現在最下兩層;
② 最下層的葉子一定集中在左部連續位置;
③ 倒數二層,若有葉子結點,一定都在右部連續位置;
④ 如果結點度爲1,則該結點只有左孩子,既不存在只有右子樹的情況;
⑤ 同樣結點數的二叉樹,完全二叉樹的深度最小。

4.4.4 線索二叉樹:

利用二叉樹結點的空指針域,存儲該結點以某種次序遍歷的前驅、後繼(線索),提高遍歷效率的同時,增強了內存空間的利用效率。加了線索的二叉鏈表稱爲線索鏈表,相應的二叉樹稱爲線索二叉樹。而以某種次序遍歷,使一個二叉樹變成線索二叉樹的過程,稱爲線索化。
線索二叉樹的結點變量,需要包含兩個成員標誌(ltag、rtag),來表示lchild、rchild是指向左右孩子,還是前驅後繼。如下:
在這裏插入圖片描述

4.5 二叉樹的遍歷

二叉樹的遍歷是指從根結點出發,按照某種次序依次訪問二叉樹中所有結點,使得每個結點被訪問一次且僅被訪問一次。

  • 前序遍歷: 若二叉樹爲空,則空操作返回;否則先訪問根結點,然後前序遍歷左子樹,再前序遍歷右子樹(根——左子樹——右子樹)。如下:
    前序遍歷
  • 中序遍歷: 若二叉樹爲空,則空操作返回;否則先遍歷根結點的左子樹,然後訪問根結點,再中序遍歷右子樹(左子樹——根——右子樹)。如下:
    中序遍歷
  • 後序遍歷: 若二叉樹爲空,則空操作返回;否則按從左到右、先葉子後結點的方式遍歷訪問左右子樹,最後訪問根結點(左子樹——右子樹——根)。如下:後序遍歷
  • 層序遍歷: 若二叉樹爲空,則空操作返回;否則從樹的第一層,即根結點開始,按從上而下、從左到右的順序逐個訪問結點。如下:
    層序遍歷

五、樹、森林、二叉樹的轉換

5.1 “樹”轉換成“二叉樹”

① 加線。在所有兄弟結點之間加一條連線;
② 去線。對樹中每個結點,只保留它與第一個孩子結點的連線,刪除它與其他孩子結點之間的連線;
③ 層次調整。以樹的根結點爲軸心,講整棵樹順時針旋轉一定角度,使其結構層次分明。注意第一個孩子是二叉樹結點的左孩子,兄弟轉換過來的孩子是結點的右孩子。
在這裏插入圖片描述

5.2 “森林”轉換成“二叉樹”

① 把每棵樹轉換爲二叉樹;
② 第一棵二叉樹不動。從第二棵二叉樹開始,依次把後一棵二叉樹的根結點,作爲前一棵二叉樹的根結點的右孩子,用線連接起來。當所有的二叉樹連接起來後,就得到了由森林轉換而來的二叉樹。
在這裏插入圖片描述

5.3 “二叉樹”轉換成“樹”

① 加線。若某結點A,存在左孩子結點B,則將B的所有右孩子結點,都作爲A的孩子,用線連接起來;
② 去線,刪除原二叉樹中所有結點與其右孩子結點的連線;
③ 層次調整。使之結構層次分明。
如下:
在這裏插入圖片描述

5.4 “二叉樹”轉換成“森林”

① 從根結點開始,若右孩子存在,則把與右孩子結點相連的線刪除。再查看分離後的二叉樹,若右孩子存在,則連線刪除……,直到所有右孩子連線都刪除爲止;
② 將每棵分離後的二叉樹轉換成樹即可。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章