資料結構和演算法-二叉樹,AVL,紅黑樹

littlexiaoshuishui發表於2020-06-14

二叉樹

前序遍歷是指,對於樹中的任意節點來說,先列印這個節點,然後再列印它的左子樹,最後列印

它的右子樹。

中序遍歷是指,對於樹中的任意節點來說,先列印它的左子樹,然後再列印它本身,最後列印它

的右子樹。

後序遍歷是指,對於樹中的任意節點來說,先列印它的左子樹,然後再列印它的右子樹,最後打

印這個節點本身。

二叉查詢樹(一個有序的二叉樹,中序遍歷,是一個有序的排列)

二叉查詢樹要求,在樹中的任意一個節點,其左子樹中的每個節點的值,都要小於這個節點的值,而右子樹節點的值都大於這個節點的值。

查詢:我們先取根節點,如果它等於我們要查詢的資料,那就返回。如果要查詢的資料比根節點的值小,那就在左子樹中遞迴查詢;如果要查詢的資料比根節點的值大,那就在右子樹中遞迴查詢。

插入:二叉查詢樹的插入過程有點類似查詢操作。新插入的資料一般都是在葉子節點上,所以我們只需要

從根節點開始,依次比較要插入的資料和節點的大小關係。

刪除:但是它的刪除操作就比較複雜了 。針對要刪除節點的子節點個數的不同,我們需要分三種情況來處理

第一種情況是,如果要刪除的節點沒有子節點,直接刪除節點,並把它的父節點指向null.

第二種情況是,如果要刪除的節點只有一個子節點(只有左子節點或者右子節點),只需要把父節點的指標指向它的子節點,空開被刪除的節點。

第三種情況是,如果要刪除的節點有兩個子節點,這就比較複雜了。我們需要找到這個節點的右子

樹中的最小節點,把它替換到要刪除的節點上。然後再刪除掉這個最小節點,因為最小節點肯定沒

有左子節點(如果有左子結點,那就不是最小節點了)

二叉查詢樹的優勢

二叉查詢樹在比較平衡的情況下,插入、刪除、查詢操作時間複雜度才是 O(logn),和陣列的二分查詢相同。

第一,雜湊表中的資料是無序儲存的,如果要輸出有序的資料,需要先進行排序。而對於二叉查詢

樹來說,我們只需要中序遍歷,就可以在 O(n) 的時間複雜度內,輸出有序的資料序列。

第二,雜湊表擴容耗時很多,而且當遇到雜湊衝突時,效能不穩定,儘管二叉查詢樹的效能不穩

定,但是在工程中,我們最常用的平衡二叉查詢樹的效能非常穩定,時間複雜度穩定在 O(logn)。

第三,籠統地來說,儘管雜湊表的查詢等操作的時間複雜度是常量級的,但因為雜湊衝突的存在,

這個常量不一定比 logn 小,所以實際的查詢速度可能不一定比 O(logn) 快。加上雜湊函式的耗時,

也不一定就比平衡二叉查詢樹的效率高。

第四,雜湊表的構造比二叉查詢樹要複雜,需要考慮的東西很多。比如雜湊函式的設計、衝突解決

辦法、擴容、縮容等。平衡二叉查詢樹只需要考慮平衡性這一個問題,而且這個問題的解決方案比

較成熟、固定。

最後,為了避免過多的雜湊衝突,雜湊表裝載因子不能太大,特別是基於開放定址法解決衝突的散

列表,不然會浪費一定的儲存空間

8.紅黑樹(可以看成不嚴格的平衡二叉樹)

先認識一下平衡二叉查詢樹(AVL),平衡二叉樹的嚴格定義是這樣的:二叉樹中任意一個節點的左右子樹的高度相差不能大於 1。但是很多平衡二叉查詢樹其實並沒有嚴格符合上面的定義,我們這個平衡的意思就是讓整棵樹左右看起來比較“對稱”、比較“平衡”,不要出現左子樹很高、右子樹很矮的情況。這樣就能讓整棵樹的高度相對來說低一些,相應的插入、刪除、查詢等操作的效率高一些。

平衡二叉查詢樹其實有很多,比如,Splay Tree(伸展樹)、Treap(樹堆)等,但是我們提到平衡二叉查詢樹,聽到的基本都是紅黑樹。它的出鏡率甚至要高於“平衡二叉查詢樹”這幾個字,有時候,我們甚至預設平衡二叉查詢樹就是紅黑樹,那我們現在就來看看這個“明星樹”。

一棵紅黑樹還需要滿足這樣幾個要求:
根節點是黑色的;
每個葉子節點都是黑色的空節點(NIL),也就是說,葉子節點不儲存資料;
任何相鄰的節點都不能同時為紅色,也就是說,紅色節點是被黑色節點隔開的;
每個節點,從該節點到達其可達葉子節點的所有路徑,都包含相同數目的黑色節點;

為什麼不使用AVL而使用紅黑樹

最常見的回答是:紅黑樹相比於AVL樹,犧牲了部分平衡性,以換取刪除/插入操作時少量的旋轉次數,整體來說,效能優於AVL樹。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章