樹的總結


BST

Binary Sort Tree:二叉查找樹,或二叉搜索樹,或二叉排序樹

性質:

    1. 若左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
    1. 若右子樹不空,則右子樹上所有結點的值均大於或等於它的根結點的值;
    1. 左、右子樹也分別爲二叉查找樹;
    1. 沒有鍵值相等的節點。

特點:對二叉查找樹的中序遍歷,是升序的序列。查找的時間複雜度 O(logN),最壞的情況下退化至O(N),因此出現了各種平衡二叉樹,以最求優雅的O(logN)。

二叉查找樹的插入過程如下:

    1. 若當前的二叉查找樹爲空,則插入的元素爲根節點;
    1. 若插入的元素值小於根節點值,則將元素插入到左子樹中;
    1. 若插入的元素值不小於根節點值,則將元素插入到右子樹中。

AVL

平衡二叉樹:(Balanced Binary Tree),平衡的BST,以發明人命名,AVL(Adelson-Velskii and Landis)

性質:如果每一個節點的左子樹和右子樹的高度差不超過1,那麼這可樹就是平衡二叉樹。

特點:判斷一個樹是否爲平衡樹,把握三點。遞歸判斷 (1)左子樹是否平衡 (2)右子樹是否平衡 (3)左子樹的高度和右子樹的高度差值低於1。查找的時間複雜度,嚴格的O(logN)。優雅的解決了BST退化成鏈表的問題,把插入,查找,刪除的時間複雜度最好情況和最壞情況都維持在O(logN)。

缺點:頻繁旋轉會使插入和刪除犧牲掉O(logN)左右的時間,不過相對BST來說,時間上穩定了很多。

自平衡操作:4種情況的失衡狀態,兩兩對稱

  • 1)LL型:如果在一個節點的左子樹的左子樹上插入一個新節點。方法:將節點右旋使其平衡。

    原A的左孩子B變爲父結點,A變爲其右孩子,而原B的右子樹變爲A的左子樹,注意旋轉之後Brh是A的左子樹。

  • 2)RR型:在一個節點的右子樹的右子樹上插入一個新節點。方法:將節點左旋使其平衡。

    原A右孩子B變爲父結點,A變爲其左孩子,而原B的左子樹Blh將變爲A的右子樹。

  • 3)LR型:在一個節點的左子樹的右子樹上插入一個新節點。方法:雙旋轉,兩步走,先讓樹中高度較低的進行一次左旋,這個時候就變成了LL型了。再進行一次右旋操作即可。

在B節點按照RR型向左旋轉一次之後,二叉樹在A節點仍然不能保持平衡,這時還需要再向右旋轉一次。

  • 4)RL型:在一個節點的右子樹的左子樹上插入一個新節點。方法:雙旋轉,先讓樹中高度較低的進行一次右旋,這個時候就變成了RR型了。再進行一次左旋操作即可。

與LR情況剛好相反,將B結點右旋,變爲RR,再讓A結點單左旋。

R-B Tree

紅黑樹:是一種自平衡二叉查找樹,複雜且高效,並且在實踐中是高效的: 它可以在O(logn)時間內做查找,插入和刪除。紅黑樹還是2-3-4樹的一種等同,它們的思想是一樣的,只不過紅黑樹是2-3-4樹用二叉樹的形式表示的。

性質:五大性質

  • 1)所有節點都是 紅色 或者 黑色,非紅即黑。

  • 2)根節點是黑色

  • 3)紅色節點的子節點不能是紅色,必須是黑色

  • 4)所有的NIL結點都是黑色(注:爲空的葉子節點)

  • 5)從任意節點出發,所有到NIL節點的路徑含有相同數量的黑色節點

如下圖所示:

紅黑樹基本操作(一):添加節點

大致步驟,將紅黑樹當作一顆二叉查找樹,將節點插入;然後,將節點着色爲紅色;最後通過旋轉和重新着色等方法,來修正,使之成爲一顆滿足五大性質的紅黑樹。

可分爲三大情況來處理:
  • 情況1:插入節點的是根節點。方法:直接把這個節點塗爲黑色

  • 情況2:插入節點的的父節點是黑色。方法:無任何操作,仍是紅黑樹。

  • 情況3:插入結點的父節點是紅色,又分爲三種小情況:

    • case 1)情況:當前節點的父節點是紅色,叔叔節點也是紅色。 方法:1、將“父節點”設爲黑色。2、將“叔叔節點”設爲黑色。3、將“祖父節點”設爲紅色。4、將“祖父節點”設爲“當前節點”;即,之後的操作,繼續轉化爲對“當前節點”的操作。
  • case 2)情況:當前節點的父節點是紅色,叔叔節點是黑色,且當前節點是其父節點的右孩子

           方法:1、將“父節點”作爲“新的當前節點”。2、以”新的當前節點“爲支點進行左旋。
    
  • case 3)情況:當前節點的父節點是紅色,叔叔節點是黑色,且當前節點是其父節點的左孩子

            方法:1、將“父節點”設爲黑色。2、將“祖父節點”設爲紅色。3、以“祖父節點”爲支點進行右旋
    

紅黑樹的基本操作(二):刪除

大致步驟,將紅黑樹當作一顆二叉查找樹,將該節點從二叉查找樹中刪除;然後,通過旋轉和重新着色等操作來修復成紅黑樹,使之重新成爲一顆紅黑樹。

第一步:
  • 情況1:被刪除的節點沒有孩子,即爲葉節點(注:不是NIL節點)。方法:直接刪除該節點

  • 情況2:被刪除的節點只有一個孩子。方法:直接刪除該節點,那麼該孩子直接頂替它的位置。

  • 情況3:被刪除的節點有兩個孩子。則找到“當前節點”的“後繼節點”,把“後繼節點”複製給“當前節點”,覆蓋它。然後刪除後繼節點。即問題往下轉移,直至遇到情況1,和情況2,停止。

    第二步:

    修復紅黑樹,通過旋轉和重新着色,使之重新成爲一顆紅黑樹。

B-tree

B-tree即B樹,B-樹,又叫平衡多路查找樹。

一顆m階的B樹(m叉樹)的特性如下:

  • 1、樹中每個節點最多含有m個孩子;

  • 2、除根節點和葉子結點外,其他每個節點至少有[ceil(m/2)]個孩子(其中ceil(x)是一個取上限的函數);

  • 3、若根節點不是葉子結點,則至少有兩個孩子(特例:整棵樹只有一個節點);

  • 4、所有的葉子結點都出現在同一層,葉子結點爲NULL,即NIL節點;

  • 5、有j個孩子的非葉節點恰好有j-1個關鍵碼,關鍵碼按遞增次序排列;

備註:B樹中的每個結點根據實際情況可以包含大量的關鍵字信息和分支(當然是不能超過磁盤塊的大小,根據磁盤驅動(disk drives)的不同,一般塊的大小在1k~4k左右);這樣樹的深度降低了,這就意味着查找一個元素只要很少結點從外存磁盤中讀入內存,很快訪問到要查找的數據。

B+tree

B+數,是應文件系統所需而產生的一種B-tree的變形樹。

與B樹的差異在於:

  • 1、有n棵子樹的節點含有n個關鍵字;(而B樹是n棵子樹有n-1個關鍵字)

  • 2、所有葉子結點中包含了全部關鍵字的信息,即指向含有這些關鍵字記錄的指針,且葉子結點本身依關鍵字的大小,自小到大的順序鏈接。(而B樹的葉子節點並沒有包括全部需要查找的信息)

  • 3、所有的非終端節點可以看成是索引部分,節點中僅含有其子樹根節點中最大(或最小的關鍵字)。而B樹的非葉子結點也包含需要查找的有效信息。

問題: 爲什麼說B±tree比B 樹更適合實際應用中操作系統的文件索引和數據庫索引?

  1. B±tree的磁盤讀寫代價更低

B±tree的內部結點並沒有指向關鍵字具體信息的指針。因此其內部結點相對B 樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。

舉個例子,假設磁盤中的一個盤塊容納16bytes,而一個關鍵字2bytes,一個關鍵字具體信息指針2bytes。一棵9階B-tree(一個結點最多8個關鍵字)的內部結點需要2個盤快。而B+ 樹內部結點只需要1個盤快。當需要把內部結點讀入內存中的時候,B 樹就比B+ 樹多一次盤塊查找時間(在磁盤中就是盤片旋轉的時間)。
  1. B±tree的查詢效率更加穩定

由於非終結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

SB-Tree

SB-Tree:Size Balanced Tree,自平衡條件:每個結點所在子樹的結點個數不小於其兄弟的兩個孩子所在子樹的結點個數。

與AVL樹的差異:

AVL 樹比較的是層數,而SB 樹比較的是 Size ,結點的多少。另一個和 AVL 不太一樣的是,SBTree 只有在插入時纔可能觸發調整,而不需要在刪除結點以後進行調整。

插入時的調整:與AVL樹類似,分爲LL,RR,LR,RL,四種情況。

TireTree

字典樹,又稱前綴樹解決字符串前綴匹配問題,查找單詞是否存在,統計以如“abc”開始的字符串的個數,實現詞頻統計等。

public static class TrieNode {
	public int path;   // 記錄有多少個字符經過
	public int end;    // 記錄有多少個字符串以此節點結尾
	public TrieNode[] nexts;  // 路
		public TrieNode() {
			path = 0;
			end = 0;
			nexts = new TrieNode[26];
		}
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章