二叉樹
前序遍歷是指,對於樹中的任意節點來說,先列印這個節點,然後再列印它的左子樹,最後列印
它的右子樹。
中序遍歷是指,對於樹中的任意節點來說,先列印它的左子樹,然後再列印它本身,最後列印它
的右子樹。
後序遍歷是指,對於樹中的任意節點來說,先列印它的左子樹,然後再列印它的右子樹,最後打
印這個節點本身。
二叉查詢樹(一個有序的二叉樹,中序遍歷,是一個有序的排列)
二叉查詢樹要求,在樹中的任意一個節點,其左子樹中的每個節點的值,都要小於這個節點的值,而右子樹節點的值都大於這個節點的值。
查詢:我們先取根節點,如果它等於我們要查詢的資料,那就返回。如果要查詢的資料比根節點的值小,那就在左子樹中遞迴查詢;如果要查詢的資料比根節點的值大,那就在右子樹中遞迴查詢。
插入:二叉查詢樹的插入過程有點類似查詢操作。新插入的資料一般都是在葉子節點上,所以我們只需要
從根節點開始,依次比較要插入的資料和節點的大小關係。
刪除:但是它的刪除操作就比較複雜了 。針對要刪除節點的子節點個數的不同,我們需要分三種情況來處理
第一種情況是,如果要刪除的節點沒有子節點,直接刪除節點,並把它的父節點指向null.
第二種情況是,如果要刪除的節點只有一個子節點(只有左子節點或者右子節點),只需要把父節點的指標指向它的子節點,空開被刪除的節點。
第三種情況是,如果要刪除的節點有兩個子節點,這就比較複雜了。我們需要找到這個節點的右子
樹中的最小節點,把它替換到要刪除的節點上。然後再刪除掉這個最小節點,因為最小節點肯定沒
有左子節點(如果有左子結點,那就不是最小節點了)
二叉查詢樹的優勢
二叉查詢樹在比較平衡的情況下,插入、刪除、查詢操作時間複雜度才是 O(logn),和陣列的二分查詢相同。
第一,雜湊表中的資料是無序儲存的,如果要輸出有序的資料,需要先進行排序。而對於二叉查詢
樹來說,我們只需要中序遍歷,就可以在 O(n) 的時間複雜度內,輸出有序的資料序列。
第二,雜湊表擴容耗時很多,而且當遇到雜湊衝突時,效能不穩定,儘管二叉查詢樹的效能不穩
定,但是在工程中,我們最常用的平衡二叉查詢樹的效能非常穩定,時間複雜度穩定在 O(logn)。
第三,籠統地來說,儘管雜湊表的查詢等操作的時間複雜度是常量級的,但因為雜湊衝突的存在,
這個常量不一定比 logn 小,所以實際的查詢速度可能不一定比 O(logn) 快。加上雜湊函式的耗時,
也不一定就比平衡二叉查詢樹的效率高。
第四,雜湊表的構造比二叉查詢樹要複雜,需要考慮的東西很多。比如雜湊函式的設計、衝突解決
辦法、擴容、縮容等。平衡二叉查詢樹只需要考慮平衡性這一個問題,而且這個問題的解決方案比
較成熟、固定。
最後,為了避免過多的雜湊衝突,雜湊表裝載因子不能太大,特別是基於開放定址法解決衝突的散
列表,不然會浪費一定的儲存空間
8.紅黑樹(可以看成不嚴格的平衡二叉樹)
先認識一下平衡二叉查詢樹(AVL),平衡二叉樹的嚴格定義是這樣的:二叉樹中任意一個節點的左右子樹的高度相差不能大於 1。但是很多平衡二叉查詢樹其實並沒有嚴格符合上面的定義,我們這個平衡的意思就是讓整棵樹左右看起來比較“對稱”、比較“平衡”,不要出現左子樹很高、右子樹很矮的情況。這樣就能讓整棵樹的高度相對來說低一些,相應的插入、刪除、查詢等操作的效率高一些。
平衡二叉查詢樹其實有很多,比如,Splay Tree(伸展樹)、Treap(樹堆)等,但是我們提到平衡二叉查詢樹,聽到的基本都是紅黑樹。它的出鏡率甚至要高於“平衡二叉查詢樹”這幾個字,有時候,我們甚至預設平衡二叉查詢樹就是紅黑樹,那我們現在就來看看這個“明星樹”。
一棵紅黑樹還需要滿足這樣幾個要求:
根節點是黑色的;
每個葉子節點都是黑色的空節點(NIL),也就是說,葉子節點不儲存資料;
任何相鄰的節點都不能同時為紅色,也就是說,紅色節點是被黑色節點隔開的;
每個節點,從該節點到達其可達葉子節點的所有路徑,都包含相同數目的黑色節點;
為什麼不使用AVL而使用紅黑樹
最常見的回答是:紅黑樹相比於AVL樹,犧牲了部分平衡性,以換取刪除/插入操作時少量的旋轉次數,整體來說,效能優於AVL樹。
本作品採用《CC 協議》,轉載必須註明作者和本文連結