Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树、二叉查找树的插入节点、二叉查找树的删除、二叉树的遍历、平衡二叉树)C 语言实现
Algorithm:樹相關算法(BBT/BST/B樹/R樹)簡介(二叉查找樹、二叉查找樹的插入節點、二叉查找樹的刪除、二叉樹的遍歷、平衡二叉樹)C++語言實現
目錄
樹的基礎知識
1、二叉樹的遍—前序、中序、后序
一、二叉樹
1、CBT
2、BST—二叉查找樹BST的增刪改查
1、BST的查找節點
2、BST的插入節點
3、BST的刪除節點
3、BBT—平衡二叉樹BBT→AVL/RBT
0、RBT紅黑樹和AVL
1、BBT的旋轉
2、BBT的插入
3、BBT的查找
4、BBT的刪除
4、堆
5、哈夫曼樹HT/最優二叉樹
二、多路查找樹:多叉樹——二叉到多叉的思考
1、多叉樹
1、多叉樹的查找與插入
2、B樹及其變種——分裂節點、合并節點
3、R樹—R樹在實踐中的應用
樹相關算法的代碼實現
1、二叉樹的遍歷——前中后、通過前中求后
2、二叉查找樹、BST的插入節點、BST的刪除
3、BBT單旋轉、雙旋轉、BBT的插入、BBT的刪除
參考文章:Algorithm:【Algorithm算法進階之路】之數據結構基礎知識
樹的基礎知識
? ? ? ?樹Tree是一種抽象數據類型ADT,或是實作這種抽象數據類型的數據結構,用來模擬具有樹狀結構性質的數據集合。它是由n(n>=1)個有限節點組成一個具有層次關系的集合。把它叫做“樹”是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具有以下的特點:
- (1)、每個節點有零個或多個子節點;
- (2)、沒有父節點的節點稱為根節點;
- (3)、每一個非根節點有且只有一個父節點;
- (4)、除了根節點外,每個子節點可以分為多個不相交的子樹;
1、二叉樹的遍—前序、中序、后序
二叉樹的遍歷,都要從先從左區域開始遍歷。
1、前序遍歷、中序遍歷、后序遍歷
注:根結點Degree、左子樹L、右子樹R
先(根)序遍歷(根左右DLR):
中(根)序遍歷(左根右LDR):BST的中序一定是遞增有序的序列!
后(根)序遍歷(左右根LRD):
結論:
(1)、二叉樹結點的DLR、LDR、LRD中,所有葉子結點的先后順序都是一致的,因為所有的葉節點都是從左到右的!
| 前序遍歷:先(根)序遍歷,根左右DLR 根節點→前序遍歷左子樹(DLR)→前序遍歷右子樹(DLR) | |
| 中序遍歷:中(根)序遍歷,左根右LDR。BST的中序一定是遞增有序的序列! 中序遍歷左子樹(LDR)→根節點→中序遍歷右子樹(LDR) (1)、比如35是因為3就是節點5的左子數;67是因為7是6的右子樹,所以先遍歷6的左子樹即空→根節點6→右子樹7 | |
| 后序遍歷:后(根)序遍歷,左右根LRD 后序遍歷左子樹(LRD)→后序遍歷右子樹(LRD)→根節點 |
2、相關結論
(1)、二叉樹結點的DLR、LDR、LRD中,所有葉子結點的先后順序都是一致的,因為所有的葉節點都是從左區域到右區域的!
3、問題類型
(1)、通過前序中序求后序
Algorithm:【Algorithm算法進階之路】之數據結構(數組、字符串、鏈表、棧、隊列、樹、圖、哈希、堆)相關習題
一、二叉樹
1、CBT—FBT一定是CBT
參考文章:Algorithm:【Algorithm算法進階之路】之數據結構基礎知識
2、BST—二叉查找樹BST的增刪改查
1、BST的查找節點
查找某節點p的過程如下:
- n 將當前節點cur賦值為根節點root;
- n 若p的值小于當前節點cur的值,查找cur的左子樹;
- n 若p的值不小于當前節點cur的值,查找cur的右子樹;
- n 遞歸上述過程,直到cur的值等于p的值或者cur為空;
- o 當然,若節點是結構體,注意定義“小于”“不小于”“等于”的具體函數。
2、BST的插入節點
原理要符合二叉樹的建立。
- n若當前的二叉查找樹為空,則插入的元素為根節點,
- n若插入的元素值小于根節點值,則將元素插入到左子樹中,
- n若插入的元素值不小于根節點值,則將元素插入到右子樹中,
- n遞歸上述過程,直到找到插入點為葉子節點。
3、BST的刪除節點
記待刪除的節點為p,分三種情況進行處理
- 待刪除點為葉子節點:p為葉子節點,直接刪除該節點,再修改p的父節點的指針
- 待刪除點只有一個孩子:若p為單支節點(即只有左子樹或右子樹),則將p的子樹與p的父親節點相連,刪除p即可。
- 待刪除點只有一個孩子:若p的左子樹和右子樹均不空,則找到p的直接后繼d(p的右孩子的最左子孫),因為d一定沒有左子樹,所以使用刪除單支節點的方法:刪除d,并讓d的父親節點dp成為d的右子樹的父親節點;同時,用d的值代替p的值;
(1)、對偶的,可以找到p的直接前驅x(p的左孩子的最右子孫),x一定沒有右子樹,所以可以刪除x,并讓x的父親節點成為x的左子樹的父親節點。
? ? ?
3、BBT—平衡二叉樹BBT→AVL/RBT
? ? ? ? 平衡二叉樹(Balanced Binary Tree)是二叉查找樹的一個變體,也是第一個引入平衡概念的二叉樹。1962年,G.M. Adelson-Velsky 和E.M. Landis發明了這棵樹,所以它又叫AVL樹。
? ? ? ? 平衡二叉樹要求對于每一個節點來說,它的左右子樹的高度之差不能超過1,如果插入或者刪除一個節點使得高度之差大于1,就要進行節點之間的旋轉,將二叉樹重新維持在一個平衡狀態。這個方案很好的解決了二叉查找BST樹退化成鏈表的問題,把插入、查找、刪除的時間復雜度最好情況和最壞情況都維持在O(logN)。
1、BBT的動機
? ? ? ? 對一棵查找樹(search tree)進行查詢/新增/刪除 等動作, 所花的時間與樹的高度h 成比例, 并不與樹的容量 n 成比例。如果可以讓樹維持矮矮胖胖的好身材, 也就是讓h維持在O(lg n)左右, 完成上述工作就很省時間。能夠一直維持好身材, 不因新增刪除而長歪的搜尋樹, 叫做balanced search tree(平衡樹)。
2、BBT的特點:
- BBT是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,并且左右兩個子樹都是一棵平衡二叉樹。
- BBT常用算法有紅黑樹、AVL、Treap、伸展樹、SBT等。
- 最小BBT的節點的公式: F(n)=F(n-1)+F(n-2)+1,這個類似于一個遞歸的數列,可以參考Fibonacci數列,1是根節點,F(n-1)是左子樹的節點數量,F(n-2)是右子樹的節點數量。
0、AVL和RBT紅黑樹
0、AVL和紅黑樹對比
- 兩者都屬于自平衡二叉樹。
- 兩者查找,插入,刪除的時間復雜度相同。
1、AVL樹—可理解為BBT
? ? ? ? ? AVL樹查找的時間復雜度為O(logN),因為樹一定是平衡的。但是由于插入或刪除一個節點時需要掃描兩趟樹,依次向下查找插入點,依次向上平衡樹,AVL樹不如紅黑樹效率高,也不如紅黑樹常用。
- AVL樹是平衡二叉搜索樹的鼻祖:AVL樹是最先發明的自平衡二叉查 找樹。
| AVL樹有兩個性質 | 它或者是一顆空二叉樹,或者是具有下列性質的二叉樹: (1)、其根的左右子樹,高度之差的絕對值不能超過1; (2)、其根的左右子樹,都是二叉平衡樹。 |
| AVL應用 | 1、Windows NT內核中廣泛存在。 |
2、紅黑樹
? ? ? ? 紅黑樹的平衡是在插入和刪除的過程中取得的。對一個要插入的數據項,插入程序要檢查不會破壞樹一定的特征。如果破壞了,程序就會進行糾正,根據需要更改樹的結構。通過維持樹的特征,保持了樹的平衡。
- 紅黑樹 并不追求“完全平衡 ”:它只要求部分地達到平衡要求,降低了對旋轉的要求,從而提高了性能。
- 紅黑樹能夠以?O(log2?n)??的時間復雜度進行搜索、插入、刪除操作。
- 任何不平衡都會在三次旋轉之內解決。
| 紅黑樹有兩個特征 | 1、節點都有顏色 2、在插入和刪除過程中,要遵循保持這些顏色的不同排列的規則。 |
| 紅黑規則 | 1、每一個節點不是紅色的就是黑色的。 2、根總是黑色的 3、如果節點是紅色的,則它的子節點必須是黑色的(反之不一定成立)。 4、從根到葉節點或空子節點的每條路徑,必須包含相同數目的黑色節點。 ? ?(空子節點是指非葉節點可以接子節點的位置。換句話說,就是一個有右子節點的節點可能接左子節點的位置,或是有左子節點的節點可能接右子節點的位置) |
| 紅黑樹的應用 | 1、廣泛用于C++的STL中,map和set都是用紅黑樹實現的。 2、IO多路復用epoll的實現采用紅黑樹組織管理sockfd,以支持快速的增刪改查。 |
1、BBT的旋轉
高度不平衡節點的兩顆子樹的高度差2,只考慮該不平衡節點本身,分四種情況分別討論。
(1)、四種分類:左左、左右、右左、右右;
(2)、四種旋轉:對稱與旋轉,左左和右右對稱;左右和右左對稱
左左和右右兩種情況是對稱的,這兩種情況的旋轉算法是一致的,只需要經過一次旋轉就可以達到目標,稱之為單旋轉。
左右和右左兩種情況也是對稱的,這兩種情況的旋轉算法也是一致的,需要進行兩次旋轉,稱之為雙旋轉。
| a、高度不平衡之左左 6節點的左子樹3節點高度比右子樹7節點大2,左子樹3節點的左子樹1節點高度大于右子樹4節點,這種情況成為左左。 | b、高度不平衡之左右 6節點的左子樹2節點高度比右子樹7節點大2,左子樹2節點的左子樹1節點高度小于右子樹4節點,這種情況成為左右。 | c、高度不平衡之右左 2節點的左子樹1節點高度比右子樹5節點小2,右子樹5節點的左子樹3節點高度大于右子樹6節點,這種情況成為右左。 | d、高度不平衡4之右右 2節點的左子樹1節點高度比右子樹4節點小2,右子樹4節點的左子樹3節點高度小于右子樹6節點,這種情況成為右右。 |
| (1)、BBT的左左—單旋轉 如圖,假設K2不平衡:為使樹恢復平衡,把K1變成根節點。K2大于K1,所以,把K2置于K1的右子樹上。K1右子樹Y大于K1,小于K2,所以,把Y置于k2的左子樹上。 左旋:就是讓左邊的孩子K1去提到上邊,升級作為爸爸,自己K2變成兒子。 | (2)、BBT的左右雙旋轉 對于左右和右左這兩種情況,單旋轉不能使它達到一個平衡狀態,要經過兩次旋轉。 以左右為例:節點K3不滿足平衡特性,它的左子樹K1比右子樹D深2層,且K1子樹更深的是右子樹K2。 |
2、BBT的插入
? ? ? ?BBT插入的方法和BST基本一致。區別是,插入完成后需要從插入的節點開始,維護一個到根節點的路徑,每經過一個節點都要維持樹的平衡。維持樹的平衡要根據高度差的特點選擇不同的旋轉算法。
3、BBT的查找
? ? ? ?BBT查找的方法和BST完全一樣。不過根據高度基本平衡存儲的特性,BBT能保持O(logN)的穩定時間復雜度,而BST則相當不穩定。
4、BBT的刪除
? ? ? ?BBT刪除的方法和BST基本一致。區別是,刪除完成后,需要從刪除節點的父親開始,向上維護樹的平衡一直到根節點。
4、堆
5、哈夫曼樹HT/最優二叉樹
二、多路查找樹:多叉樹——二叉到多叉的思考
1、多叉樹
一個節點存一個值,則有2個孩子:W
一個節點存兩個值,則有3個孩子:MO
一個節點存三個值,則有4個孩子:MO
1、多叉樹的查找與插入
2、B樹及其變種——分裂節點、合并節點
1、B樹的定義——m階B樹需要滿足的條件
- (1)、每個結點至多有m個孩子;
- (2)、除根結點外,其他結點至少有m/2個孩子;
- (3)、根結點至少有2個孩子;
- (4)、所有葉結點在同一層;
- (5)、有α個孩子的非葉結點有α-1個關鍵字;結點內部,關鍵字遞增排列。
2、B樹的變種
3、R樹—R樹在實踐中的應用
樹相關算法的代碼實現
1、二叉樹的遍歷——前中后、通過前中求后
(1)、前序遍
(2)、中序遍歷
(3)、后序遍歷
(4)、T2、通過前序中序求后序
2、二叉查找樹、BST的插入節點、BST的刪除
(2)、二叉查找樹插入節點
(3)、二叉查找樹BST的刪除
3、BBT單旋轉、雙旋轉、BBT的插入、BBT的刪除
(1)、左左單旋轉
(2)、雙旋轉
(3)、平衡二叉樹的插入
(4)、平衡二叉樹的刪除
總結
以上是生活随笔為你收集整理的Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树、二叉查找树的插入节点、二叉查找树的删除、二叉树的遍历、平衡二叉树)C 语言实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Algorithm:C++语言实现之字符
- 下一篇: Algorithm:【Algorithm