Java 樹結構的算法
基本概念
定義
**樹(Tree)**是n(n>=0)個節點的有限集。n=0時稱爲空樹。在任意一顆非空樹中:
(1)有且僅有一個特定的稱爲根(Root)的節點;
(2)當n>1時,其餘節點可分爲m(m>0)個互不相交的有限集T1、T2、…、Tn,其中每一個集合本身又是一棵樹,並且稱爲根的子樹。
此外,樹的定義還需要強調以下兩點:
(3)n>0時根節點是唯一的,不可能存在多個根節點,數據結構中的樹只能有一個根節點。
(4)m>0時,子樹的個數沒有限制,但它們一定是互不相交的。
節點的度
定義:節點擁有的子樹數目稱爲節點的度。例如:圖3.2中標註了圖3.1所示樹的各個節點的度。
節點關係
節點子樹的根節點爲該節點的孩子節點。相應該節點稱爲孩子節點的雙親節點。圖3.2中,A爲B的雙親節點,B爲A的孩子節點。
同一個雙親節點的孩子節點之間互稱兄弟節點。圖3.2中,B與C互爲兄弟節點,GHI互爲兄弟節點,EF互爲兄弟節點。
節點層次
從根節點開始,根節點爲第一層,根的孩子爲第二層,以此類推。例如:圖3.4表示了圖3.1所示樹的層次關係
樹的深度
樹中節點的最大層次數稱爲樹的深度或高度。
二叉樹
定義
二叉樹是n(n>=0)個節點的有限集合,該集合或者爲空集(稱爲空二叉樹),或者由一個根節點和兩棵互不相交的、分別稱爲根節點的左子樹和右子樹組成。
圖4.1展示了一棵一般二叉樹
二叉樹特點
由二叉樹的定義,以及圖中所示的二叉樹的分析可以得出二叉樹具有以下幾個特點:
(1)每個節點最多有兩顆子樹,所以二叉樹中不存在度大於2的節點。
(2)左子樹和右子樹是有順序的,次序不能任意顛倒。
(3)即使樹中某節點只有一棵子樹,也要區分它是左子樹還是右子樹。
二叉樹性質
(1)在二叉樹的第i層上最多有2i-1 個節點 。(i>=1)
(2)二叉樹中如果深度爲k,那麼最多有2k-1個節點。(k>=1)
(3)n0=n2+1 n0表示度數爲0的節點數,n2表示度數爲2的節點數。
(4)在完全二叉樹中,具有n個節點的完全二叉樹的深度爲[log2n]+1,其中[log2n]是向下取整。
(5)若對含 n 個節點的完全二叉樹從上到下且從左至右進行 1 至 n 的編號,則對完全二叉樹中任意一個編號爲 i 的節點有如下特性:
(5)- 1,若 i=1,則該節點是二叉樹的根,無雙親, 否則,編號爲 [i/2] 的節點爲其雙親節點;
(5)- 2,若 2i>n,則該節點無左孩子, 否則,編號爲 2i 的節點爲其左孩子節點;
(5)- 3,若 2i+1>n,則該節點無右孩子節點, 否則,編號爲2i+1 的節點爲其右孩子節點。
斜樹
所有的節點都只有左子樹的二叉樹叫左斜樹。所有節點都是隻有右子樹的二叉樹叫右斜樹,這兩者統稱爲斜樹。
滿二叉樹
在一棵二叉樹中。如果所有分支節點都存在左子樹和右子樹,並且所有葉子都在同一層上,這樣的二叉樹稱爲滿二叉樹。
滿二叉樹的特點有:
(1)葉子只能出現在最下一層。出現在其它層就不可能達成平衡。
(2)非葉子節點的度一定是2。
(3)在同樣深度的二叉樹中,滿二叉樹的節點個數最多,葉子節點數最多。
完全二叉樹
完全二叉樹:對一顆具有n個節點的二叉樹按層編號,如果編號爲i(1<=i<=n)的節點與同樣深度的滿二叉樹中編號爲i的節點在二叉樹中位置完全相同,則這棵二叉樹稱爲完全二叉樹。 圖4.6爲一棵完全二叉樹
完全二叉樹特點:
(1)葉子節點只能出現在最下層和次下層。
(2)最下層的葉子節點集中在樹的左部。
(3)倒數第二層若存在葉子節點,一定在右部連續位置。
(4)如果節點度爲1,則該節點只有左孩子,即沒有右子樹。
(5)同樣節點數目的二叉樹,完全二叉樹深度最小。
二叉樹的存儲結構
(1)順序存儲
二叉樹的順序存儲結構就是使用一維數組存儲二叉樹中的節點,並且節點的存儲位置,就是數組的下標索引
例如:所示的一棵完全二叉樹採用順序存儲方式,表示:
當二叉樹爲完全二叉樹時,節點數剛好填滿數組。那麼當二叉樹不爲完全二叉樹時,採用順序存儲形式如何呢?
其中,未填充節點表示節點不存在。那麼圖4.7.2所示的二叉樹的順序存儲結構如圖4.7.3所示:
其中,∧表示數組中此位置沒有存儲節點。此時可以發現,順序存儲結構中已經出現了空間浪費的情況。
右斜樹極端情況
採用順序存儲的方式是十分浪費空間的。因此,順序存儲一般適用於完全二叉樹
二叉鏈表
既然順序存儲不能滿足二叉樹的存儲需求,那麼考慮採用鏈式存儲。由二叉樹定義可知,二叉樹的每個節點最多有兩個孩子。因此,可以將節點數據結構定義爲一個數據和兩個指針域。表示方式如圖所示
二叉搜索樹
定義
二叉搜索樹又稱二叉查找樹,亦稱爲二叉排序樹。設x爲二叉查找樹中的一個節點,x節點包含關鍵字key,節點x的key值記爲key[x]。如果y是x的左子樹中的一個節點,則key[y] <= key[x];如果y是x的右子樹的一個節點,則key[y] >= key[x]。
(1)若左子樹不空,則左子樹上所有節點的值均小於它的根節點的值;
(2)若右子樹不空,則右子樹上所有節點的值均大於它的根節點的值;
(3)左、右子樹也分別爲二叉搜索樹;
不是一棵二叉搜索樹
節點結構
二叉樹的節點結構通常包含三部分,其中有:左孩子的指針,右孩子指針以及數據域。節點的圖示如下:
創建二叉搜索樹
查找
查找流程:
(1)如果樹是空的,則查找結束,無匹配。
(2)如果被查找的值和節點的值相等,查找成功。
(3)如果被查找的值小於節點的值,遞歸查找左子樹,
(4)如果被查找的值大於節點的值,遞歸查找右子樹,
插入
插入流程
(1)先檢測該元素是否在樹中已經存在。如果已經存在,則不進行插入;
(2)若元素不存在,則進行查找過程,並將元素插入在查找結束的位置。
刪除
刪除節點爲葉子節點
刪除葉子節點的方式最爲簡單,只需查找到該節點,直接刪除即可。
刪除的節點只有左子樹
刪除的節點若只有左子樹,將節點的左子樹替代該節點位置。
刪除的節點只有右子樹
刪除的節點若只有右子樹,將節點的右子樹替代該節點位置。
刪除的節點既有左子樹又有右子樹。
若刪除的節點既有左子樹又有右子樹,這種節點刪除過程相對複雜。其流程如下:
(1)遍歷待刪除節點的左子樹,找到其左子樹中的最大節點,即刪除節點的前驅節點;
(2)將最大節點代替被刪除節點;
(3)刪除左子樹中的最大節點;
(4)左子樹中待刪除最大節點一定爲葉子節點或者僅有左子樹。按照之前情形刪除即可。
注:同樣可以使用刪除節點的右子樹中最小節點,即後繼節點代替刪除節點,此流程與使用前驅節點類似。
前驅節點
節點val值小於該節點val值並且值最大的節點
後繼節點
節點val值大於該節點val值並且值最小的節點
平衡二叉樹
平衡因子
**定義:**某節點的左子樹與右子樹的高度(深度)差即爲該節點的平衡因子(BF,Balance Factor),平衡二叉樹中不存在平衡因子大於1的節點。在一棵平衡二叉樹中,節點的平衡因子只能取-1、1或者0。
平衡因子過大不在這範圍之內會造成左旋和右旋,來形成自平衡二叉樹(AVL)
左旋和右旋:
https://xiaozhuanlan.com/topic/2937850641
2-3樹
前面講到了二叉搜索樹(BST)和二叉平衡樹(AVL),二叉搜索樹在最好的情況下搜索的時間複雜度爲O(logn),但如果插入節點時,插入元素序列本身就是有序的,那麼BST樹就退化成一個線性表了,搜索的時間複雜度爲O(n)。
如果想要減少比較次數,就需要降低樹的高度。在插入和刪除節點時,要保證插入節點後不能使葉子節點之間的深度之差大於1,這樣就能保證整棵樹的深度最小,這就是AVL樹解決BST搜索性能降低的策略。但由於每次插入或刪除節點後,都可能會破壞AVL的平衡,而要動態保證AVL的平衡需要很多操作,這些操作會影響整個數據結構的性能,除非是在樹的結構變化特別少的情形下,否則AVL樹平衡帶來的搜索性能提升有可能還不足爲了平衡樹所帶來的性能損耗。
因此,引入了2-3樹來提升效率。2-3樹本質也是一種平衡搜索樹,但2-3樹已經不是一棵二叉樹了,因爲2-3樹允許存在3這種節點,3-節點中可以存放兩個元素,並且可以有三個子節點。
定義
(1)2-3樹要麼爲空要麼具有以下性質:
(2)對於2-節點,和普通的BST節點一樣,有一個數據域和兩個子節點指針,兩個子節點要麼爲空,要麼也是一個2-3樹,當前節點的數據的值要大於左子樹中所有節點的數據,要小於右子樹中所有節點的數據。
(3)對於3-節點,有兩個數據域a和b和和三個子節點指針,左子樹中所有的節點數據要小於a,中子樹中所有節點數據要大於a而小於b,右子樹中所有節點數據要大於b。
性質
(1)對於每一個結點有1或者2個關鍵碼。
(2)當節點有1個關鍵碼的時,節點有2個子樹。
(3)當節點有2個關鍵碼時,節點有3個子樹。
(4)所有葉子點都在樹的同一層
增刪改查:
http://www.360doc.com/content/19/0213/21/58006001_814757954.shtml
結語
2-3 樹作爲一種平衡查找樹,查詢效率比普通的二叉排序樹要穩定許多。但是2-3樹需要維護兩種不同類型的結點,查找和插入操作的實現需要大量的代碼,而且它們所產生的額外開銷可能會使算法比標準的二叉查找樹更慢。
2-3-4樹
- https://xiaozhuanlan.com/topic/7128365094
ps:我沒看出來這個和紅黑樹和二叉樹有什麼等價關係?
答:
2-3-4樹和紅黑樹的等價關係
如果一棵樹滿足紅黑樹,把紅色節點收縮到其父節點,就變成了2-3-4樹,所有紅色節點都與其父節點構成3或4節點,其它節點爲2節點。一顆紅黑樹對應唯一形態的2-3-4樹,但是一顆2-3-4樹可以對應多種形態的紅黑樹(主要是3節點可以對應兩種不同的紅黑樹形態)。
紅黑樹的特點總結
-
搜索樹用於查詢
-
但是在自增長時,搜索樹的查詢效率降低,於是就有了平衡二叉樹
-
平衡二叉樹的查詢效率很高,但是在增加和刪除元素時,會進行重新的平衡,自旋,次數較多導致效率較低
-
紅黑樹 的定義:到葉子節點的高度可以最大N+N(黑樹必須是N,另外一個紅樹可以是N),也就是紅黑樹可以不是完全的平衡二叉樹。這樣的效果是減少了自選、平衡次數,但是還是平衡二叉樹的查詢效率最高
-
B-樹 特例是2- 3樹 注意其 增加和刪除元素的邏輯,每個樹中的節點既保存索引還有衛星數據(真實數據)
所以在查詢效率不穩定,前面找到了則就快,找不到就慢了,因爲是2-3樹相對可以減少IO次數
-
B+樹 性質:每個節點中的個數決定了其子樹的個數,所有的衛星數據都在葉子節點中,並且是用鏈表中進行連接。這樣的查詢穩定性較高,並且節點個數的限制,每個節點可以有更多的元素,IO次數也會減少
完全的平衡二叉樹。這樣的效果是減少了自選、平衡次數,但是還是平衡二叉樹的查詢效率最高
-
B-樹 特例是2- 3樹 注意其 增加和刪除元素的邏輯,每個樹中的節點既保存索引還有衛星數據(真實數據)
所以在查詢效率不穩定,前面找到了則就快,找不到就慢了,因爲是2-3樹相對可以減少IO次數
-
B+樹 性質:每個節點中的個數決定了其子樹的個數,所有的衛星數據都在葉子節點中,並且是用鏈表中進行連接。這樣的查詢穩定性較高,並且節點個數的限制,每個節點可以有更多的元素,IO次數也會減少