深入淺出數據結構(樹篇)

前言:

此篇爲數據結構相關內容連載第二篇,爲博主近期總結所得,如有錯誤,請指出!我及時更正!

1. 樹

1.1 名詞解釋

樹這個數據結構用到了遞歸的概念:樹的子樹還是樹;
度:節點的子樹個數;
樹的度:樹中任意節點的度的最大值;
兄弟:兩節點的parent相同;
層:根在第一層,以此類推;
高度:葉子節點的高度爲1,根節點高度最高;
有序樹:樹中各個節點是有次序的;
森林:多個樹組成;

1.2 樹的存儲結構
  • 雙親表示法——在每個結點的結構中,附設一個字段記錄其雙親結點在數組中的位置
  • 孩子表示法——每個結點有多個指針域,其中每個指針都指向一顆子樹的根結點
  • 孩子兄弟表示法——任意一棵樹,它的結點的第一個孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。因此,我們設置兩個指針,分別指向該節點的第一個孩子和此節點的右兄弟。
    注:第一種方法與第二種方法合併組合成雙親孩子表示法。
      第三種方法最大的好處就是把一顆複雜的樹變成一顆二叉樹。可以充分利用二叉樹的特性與算法來處理這顆樹。
    在這裏插入圖片描述
1.3 樹的種類
  • 無序樹:樹中任意節點的子結點之間沒有順序關係,這種樹稱爲無序樹,也稱爲自由樹;
  • 有序樹:樹中任意節點的子結點之間有順序關係,這種樹稱爲有序樹;
  • 二叉樹:每個節點最多含有兩個子樹的樹稱爲二叉樹;
  • 完全二叉樹
  • 滿二叉樹
  • 斜樹
  • 平衡二叉樹
  • 霍夫曼樹:帶權路徑最短的二叉樹稱爲哈夫曼樹或最優二叉樹;
二叉樹

1.特點:每個結點最多隻有兩個子結點,可以沒有或者只有一個。
  左子樹和右子樹是有順序的,次序不能任意顛倒。
2.分類:
斜樹:所有節點都只有左子樹的二叉樹叫做左斜樹,所有節點都只有右節點的二叉樹叫做右斜樹,這兩者統稱爲斜樹。

滿二叉樹:除了最下面一層的葉子結點外,其他結點都有兩個子結點;
完全二叉樹:除了最下面一層的葉子結點外,其他各層結點數達到最大個數,而且最後一層葉子結點按照從左到右的順序連續存在,只缺最後一層若干結點;
在這裏插入圖片描述

二叉樹的性質
  1. 第i層至多有2^i -1個節點;
  2. 深度爲k的樹最多有2^k -1個節點;
  3. 任意二叉樹,度爲0的節點數=度爲2的節點數+1;
  4. 如果i爲父親的編號,則孩子的編號爲2i和2i+1;
  5. 如果孩子的編號爲k,則父親的編號爲floor(k/2);
存儲方式

順序存儲:只適用於完全二叉樹;
在這裏插入圖片描述
二叉樹的順序存儲結構用一維數組存儲二叉樹中的結點,並且結點的存儲位置,也就是數組的下標要體現出結點之間的邏輯關係。
就是從根結點開始一層層地按順序存儲在數組裏,但是隻適用於完全二叉樹,因爲非完全二叉樹的話,可能會浪費大量的存儲空間。
鏈式存儲:最通用的存儲方法;

因爲二叉樹最多有兩個孩子,所以二叉鏈表擁有一個數據域和兩個指針域。
如果有需要還可以再增加一個指向其雙親的指針域,那就稱爲三叉鏈表。

二叉樹的遍歷
  • 先序:先訪問結點,後是左子樹,到右子樹;
  • 中序:先左子樹,後結點,最後是右子樹;
  • 後序:先左子樹,後右子樹,最後結點;
  • 層序:從上到下,從左到右依次遍歷每一層中的每一個節點。

例如:求下面樹的三種遍歷
在這裏插入圖片描述
前序遍歷:abdefgc
中序遍歷:debgfac
後序遍歷:edgfbca

[範例1:二叉樹遍歷]

參見範例代碼BinaryTree1 {也可以用棧來記錄並輸出}

[範例2:完全二叉樹]

參見範例代碼BinTreeTraverse2 {也可以用棧來記錄並輸出}

[對於1中的普通二叉樹,可以變成完全二叉樹處理,比如缺少的位置補充0,打印的時候不輸出0]

樹、森林與二叉樹的轉換

注:面對複雜的樹與森林都可以轉換成簡單二叉樹來進行處理,由於二叉樹至多隻有兩個節點,變化較少,很多性質與算法被研究出來,使用方便。

BST二叉排序樹(二叉搜索樹)

特點:

  1. 所有非葉子結點至多擁有兩個兒子(Left和Right);
  2. 所有結點存儲一個關鍵字;
  3. 非葉子結點的左指針指向小於其關鍵字的子樹,右指針指向大於其關鍵字的子樹;
  4. 其他的左右子樹也分別爲二叉查找樹
  5. 二叉查找樹是動態查找表,在查找的過程中可見添加和刪除相應的元素,在這些操作中需要保持二叉查找樹的以上性質。

如果BST樹的所有非葉子結點的左右子樹的結點數目均保持差不多(平衡),那麼B樹
的搜索性能逼近二分查找;但它比連續內存空間的二分查找的優點是,改變BST樹結構
(插入與刪除結點)不需要移動大段的內存數據,甚至通常是常數開銷;

在這裏插入圖片描述
但BST樹在經過多次插入與刪除後,有可能導致不同的結構:
右邊也是一個BST樹,但它的搜索性能已經是線性的了;同樣的關鍵字集合有可能導致不同的樹結構索引;所以,使用BST樹還要考慮儘可能讓BST樹保持左圖的結構,和避免右圖的結構,也就是所謂的“平衡”問題;

AVL平衡二叉搜索樹


含有相同節點的二叉查找樹可以有不同的形態,而二叉查找樹的平均查找長度與樹的深度有關,所以需要找出一個查找平均長度最小的一棵,那就是平衡二叉樹(圖b),具有以下性質:

  1. 要麼是棵空樹,要麼其根節點左右子樹的深度之差的絕對值不超過1;
  2. 其左右子樹也都是平衡二叉樹;
  3. 二叉樹節點的平衡因子定義爲該節點的左子樹的深度減去右子樹的深度。則平衡二叉樹的所有節點的平衡因子只可能是-1,0,1。
    【平衡因子BF=左子樹深度-右子樹深度】
RBT 紅黑樹

AVL是嚴格平衡樹,因此在增加或者刪除節點的時候,根據不同情況,旋轉的次數比紅黑樹要多;
紅黑是弱平衡的,用非嚴格的平衡來換取增刪節點時候旋轉次數的降低;
所以簡單說,搜索的次數遠遠大於插入和刪除,那麼選擇AVL樹,如果搜索,插入刪除次數幾乎差不多,應該選擇RB樹。
在這裏插入圖片描述
 紅黑樹是一種自平衡二叉樹,在平衡二叉樹的基礎上每個節點又增加了一個顏色的屬性,節點的顏色只能是紅色或黑色。具有以下性質:

  1. 根節點只能是黑色;
  2. 紅黑樹中所有的葉子節點後面再接上左右兩個空節點,這樣可以保持算法的一致性,而且所有的空節點都是黑色;
  3. 其他的節點要麼是紅色,要麼是黑色,紅色節點的父節點和左右孩子節點都是黑色,及黑紅相間;
  4. 在任何一棵子樹中,從根節點向下走到空節點的路徑上所經過的黑節點的數目相同,從而保證了是一個平衡二叉樹。
線索二叉樹

二叉鏈表有很多浪費的空指針可以利用,線索二叉樹給二叉樹的查找與遍歷帶來了高效率。
  指向前驅和後繼的指針稱爲線索,加上線索的二叉鏈表稱爲線索鏈表,相應的二叉樹就稱爲線索二叉樹。
  對二叉樹以某種次序遍歷使其變爲線索二叉樹的過程稱爲線索化。
  二叉鏈表充分利用了空指針域的空間,又保證了創建過程時的一次遍歷就可以終生享用的前驅後繼的信息。因此,如果所用的二叉樹需經常遍歷或查找結點時需要某種遍歷序列中的前驅後繼,那麼採用線索二叉樹的存儲結構是非常不錯的選擇

哈弗曼樹(最優二叉樹)

從樹中的一個結點到另一個結點之間的分支構成兩個結點之間的路徑,路徑上的分支數目稱作路徑長度。
樹的路徑長度就是從樹的根結點到每一結點長度之和。
帶權路徑長度最小的二叉樹稱爲哈夫曼樹。【每個節點帶權值】

B-,B+,B*樹

請移步我之前的博客,深入淺出數據庫索引,有相應介紹

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