1. 程式人生 > >資料結構和演算法分析:第四章 樹

資料結構和演算法分析:第四章 樹

4.1預備知識

樹(tree)可以用幾種方式定義。定義樹的一種自然的方式使遞迴的方式。一棵樹使一些節點的集合。這個集合可以是空集;若不是空集,則樹由稱做為根(root)的節點r以及0個或多個非空的樹集合T1、T2、T3組成,這些子樹的每一課根都被來自根r的一條又向邊(edge)所連線。 在這裡插入圖片描述

樹的基本概念

  1. 樹葉:沒有兒子的節點
  2. 兄弟:具有相同父親的節點
  3. 祖父:從根到該節點所經分支上的所有節點;
  4. 孫子:以某節點為根的子樹中任一節點都稱為該節點的子孫;
  5. 路徑:從節點n1到nk的路徑的定義為節點n1,n2,n3,n4…nk的一個序列,使得對於節點ni是ni+1的父親。這條路徑的長是為該路徑上的邊的條數。
  6. 樹的深度:從樹的根節點到ni的唯一路徑的長
  7. 樹的高度:從ni到一片樹葉的最長路徑的長度

4.1.1 樹的實現

在這裡插入圖片描述

4.1.2 樹的遍歷和應用

  • 先序遍歷:在先序遍歷中,對節點的處理工作是在它的諸兒子節點被處理之前處理的(pre)。比如UNIX檔案系統中的目錄結構遍歷
  • 後序遍歷。在後序遍歷中,一個節點處的工作是它的諸兒子節點被計算後進行的。比如統計UNXI檔案系統中資料夾的磁碟區塊個數。

4.2 二叉樹

二叉樹是一棵樹,其中樹的每個節點都不能有多於兩個的兒子。有一種特殊的二叉樹,即二叉查詢樹,其深度的平均值是O(logN),並且這些操作的平均時間是O(logN)。

4.2.1 實現

在這裡插入圖片描述

4.2.2 列子:表示式樹

在這裡插入圖片描述

圖中顯示的就是一個表示式樹的列子。表示式樹的樹葉是運算元,如常數或者變數名,而其他節點都是操作符。

  • 中綴表示式:中序遍歷(左子樹,節點,右子樹)
  • 字尾表示式:後序遍歷(左子樹,右子樹,節點)
  • 字首表示式:前序遍歷(節點,左子樹,右子樹)

4.3 查詢ADT–二叉查詢樹

基本概念:使二叉樹成為二叉查詢樹的性質是,對於樹的每一個節點X,它的左子樹的所有項的值小於X中的項,而它的右子樹中所有項的值大於X中的項。

在這裡插入圖片描述

二叉查詢樹的平均深度是O(logN),並且操作的平均執行時間是O(logN)。

在這裡插入圖片描述

4.3.1 contains方法

在這裡插入圖片描述

4.3.2 findMin方法和findMax方法

在這裡插入圖片描述

4.3.3 insert方法

在這裡插入圖片描述

4.3.4 remove方法

如果節點是一片樹葉,那麼它可以立即被刪除。如果節點有一個兒子,則該節點可以在其父節點調整自己的鏈以繞過該節點後被刪除。

複雜的情況處理有兩個兒子的節點。一般的刪除策略是用其右子樹的最小的資料(很容易找到)代替該節點的資料並遞迴地刪除那個節點。因為右子樹中最小的節點不可能有左兒子,所以第二次remove就要容易。

如果刪除的次數不多,通常使用的是**惰性刪除**:當一個元素要被刪除的時候,它仍留在樹中,而只是標記為刪除。

4.3.5 平均情況分析

假設所有的插入序列都是等可能的,則樹的所有節點的平均深度為O(logN)

二叉查詢樹的平均執行時間是O(logN)

  • 問題:如果一顆樹的輸入預先排序好的資料,那麼一連串的insert操作將花費二次的時間,而連結串列實現的代價會非常巨大,因此樹將只由那些沒有左兒子的節點組成。一種解決方法就是要有一個稱為平衡的附加結構條件:任何節點的深度都不能過深。

所以引入了平衡二叉查詢樹:AVL樹

4.4 AVL樹

AVL樹是帶有平衡條件的二叉查詢樹。這個平衡條件必須要容易保持,並且它保證樹的深度必須是O(logN)

一顆AVL樹是其每個節點的左子樹和右子樹的高度差為1的二叉查詢樹。

4.4.1 單旋轉

在這裡插入圖片描述 在這裡插入圖片描述

4.4.2 左右雙旋轉

在這裡插入圖片描述 在這裡插入圖片描述

4.5 伸展樹

伸展樹:它保證從空樹開始連續M次對樹的操作最多花費O(MlogN)時間。

一般來說,當M次操作的序列總的最壞情形執行時間為O(Mf(N)),我們就說他的攤還代價是O(logN)

伸展樹的基本想法是:當一個節點被訪問後,它就要經過一系列AVL樹的旋轉被推到跟節點上。

4.5.2 伸展

在這裡插入圖片描述

4.6 再探樹的遍歷

  • 中序遍歷:該方法能夠解決將項排序的問題。正如我們所看到的,這類程式當用於二叉查詢樹的時候則稱為中序遍歷。(左子樹,根節點,右子樹)

  • 後序遍歷:該方法可以用於遍歷樹的高度。(左子樹,右子樹,根節點)

  • 前序遍歷:該方法用於遍歷樹的深度。(根節點,左子樹,右子樹)

  • 層序遍歷:在層序遍歷中,所有深度為d的節點都要在深度為d+1節點之前進行處理。層次遍歷與其他型別遍歷不同的地方在於它不是遞迴地執行;它需要使用到佇列,而不使用遞迴所默示的棧。

4.7 B樹

磁碟的代價太高了

首先,簡單說一下B樹產生的原因。B樹是一種查詢樹,我們知道,這一類樹(比如二叉查詢樹,紅黑樹等等)最初生成的目的都是為了解決某種系統中,查詢效率低的問題。B樹也是如此,它最初啟發於二叉查詢樹,二叉查詢樹的特點是每個非葉節點都只有兩個孩子節點。然而這種做法會導致當資料量非常大時,二叉查詢樹的深度過深,搜尋演算法自根節點向下搜尋時,需要訪問的節點也就變的相當多。如果這些節點儲存在外儲存器中,每訪問一個節點,相當於就是進行了一次I/O操作,隨著樹高度的增加,頻繁的I/O操作一定會降低查詢的效率。

這裡有一個基本的概念,就是說我們從外儲存器中讀取資訊的步驟,簡單來分,大致有兩步:

  1. 找到儲存這個資料所對應的磁碟頁面,這個過程是機械化的過程,需要依靠磁臂的轉動,找到對應磁軌,所以耗時長。
  2. 讀取資料進記憶體,並實施運算,這是電子化的過程,相當快。 綜上,對於外儲存器的資訊讀取最大的時間消耗在於尋找磁碟頁面。那麼一個基本的想法就是能不能減少這種讀取的次數,在一個磁碟頁面上,多儲存一些索引資訊。B樹的基本邏輯就是這個思路,它要改二叉為多叉,每個節點儲存更多的指標資訊,以降低I/O運算元。

在這裡插入圖片描述

4.8 標準庫中的集合與對映

4.8.1 關於Set介面

Set 介面不允許重複的Collection。有介面SortedSet給出的一種特殊型別的Set保證其中的各項處於有序狀態。

由Set所要求的一些獨特的操作是一些插入、刪除以及執行基本查詢的能力。保持各項以有序狀態的Set的實現是TreeSet。

get操作和add操作

4.8.2 關於Map介面

Map是一個介面,代表由關鍵字以及它們的值組成的一些項的集合。關鍵字必須是唯一的,但是若干關鍵字可以對映到一些相同的值。因此值不必是唯一的。

在SortedMap介面中,對映中的關鍵字保持邏輯上是有序狀態。SortedMap介面的一種實現是TreeMap類。Map的基本操作包括isEmpty、clear、size等方法。 在這裡插入圖片描述