概念數據結構
樹是一種重要的非線性數據結構,直觀地看,它是數據元素(在樹中稱爲結點)按分支關係組織起來的結構,很象天然界中的樹那樣。 樹是由結點或頂點和邊組成的(多是非線性的)且不存在着任何環的一種數據結構。沒有結點的樹稱爲空(null或empty)樹。一棵非空的樹包括一個根結點,還(極可能)有多個附加結點,全部結點構成一個多級分層結構性能
結點:下面就是一個簡單的樹, 每個元素都稱爲一個結點,而最頂端的是根結點,最末端的是葉子結點, 每一個結點有零個或多個子結點;每個非根結點有且只有一個父結點;除了根結點外,每一個子結點能夠分爲多個不相交的子樹 優化
度:度就是一棵樹裏面最大的寬度,下圖樹(包含子樹)的子結點數最大都不超過2因此該樹的度爲2spa
深度: 由根結點到葉子結點組成該樹各結點的最大層次3d
二叉樹blog
二叉樹又分爲二叉查找樹、徹底二叉樹、滿二叉樹、平衡二叉樹、紅黑樹、B樹 索引
爲何二叉樹也還要區分那麼多種類型?由於單種二叉樹不能徹底保證咱們運行或儲存效率,因此須要多種類型二叉樹應對不一樣的使用場景內存
下面先看一下二叉查找樹get
錄入的順序 爲 E-->F-->C-->B-->D-->A--Git
二叉樹與樹的區別
1.樹的度沒有限制,二叉樹的度最大爲2
2.二叉樹每一個子樹都是有序的,例如二叉樹的左子樹若是非空,左子樹因此結點的值都小於根節點的值,若是右子樹非空,則右子樹全部結點的值都大於根結點的值(左小右大)
由於二叉樹左小右大的特色,因此二叉查找樹有個比較極端的狀況
錄入的順序 爲 A-->B-->C-->D-->E
從小到大的開始錄入,大的永遠在右邊,就形成了右斜樹,與鏈表(線性結構)同樣這種樹並不能保證咱們的運行效率
平衡二叉樹(AVL樹)
平衡二叉樹是基於二叉查找樹優化而來的
錄入順序: A-->B-->C-->D-->E-->F
錄入順序與通常二叉樹同樣,都是從小到大開始錄入,可是平衡二叉樹每次插入數據會判斷數據的大小,從而進行左右旋轉,使得咱們的數據分佈均勻,保證了必定的運行效率
平衡二叉樹與二叉查找樹的區別主要體如今二叉查找樹的根結點不能變,平衡二叉樹爲了保證根結點左右子樹的層級差不超過1,因此會進行左右旋轉操做,這個時候根結點就會發生改變
優勢:由於左右子樹結點數量相差較少,因此查詢速度極快
缺點:插入數據時候由於旋轉次數不肯定,因此插速度會相對慢
紅黑樹
性質:
紅黑樹與平衡二叉樹類似,平衡二叉樹基於 根結點左右子樹的層級差不超過1 進行旋轉操做,而紅黑樹則是基於 沒有任何一條路徑比其餘路徑長兩倍以上進行(旋轉次數不超過3次,新增不超過2次,刪除不超過3次)旋轉
錄入順序: A-->B-->C-->D-->E-->F-->G
錄入順序: A-->B-->C-->D-->E-->F-->G-->H
由第一張紅黑樹圖能夠看出,紅黑樹的平衡度並無AVL樹平衡度那麼嚴格(只保持黑結點平衡)因爲旋轉次數是保證在3之內的,因此插入或刪除結點時候性能要比平衡二叉樹好
B樹 --- Balance-tree(平衡多路查找樹)
下面是一棵三階的B樹
錄入順序: A-->B-->C-->D-->E-->F-->G-->H
階:每一個B樹都有個指定的階(M),階決定了每一個結點最多擁有多少個子結點,例如三階B樹每一個結點最多隻能擁有三個子結點
階與度不同,上圖樹的度爲2,階爲3,可是階決定度的最大值
關鍵字:例如每個結點裏面的值就是一個關鍵字,例如,該結點就有2個關鍵字,G和H
B樹的性質
1.每一個結點裏面的關鍵字數量最多爲M-1,根節點最少能夠只有1個關鍵字,非根節點至少有M/2(上取整)個關鍵字。
2.每一個結點至少有2個子結點,葉子結點除外
3.除根結點之外的全部結點(不包括葉子結點)的度數正好是關鍵字總數加1
4.B樹的葉子結點都是在同一層
例如如今要錄入一個A-E的三階B樹
先錄入A和B
接下來要錄入C,由於根結點的關鍵字數量爲1到M-1和每一個結點至少有2個子結點,因此錄入C的時候應該B做爲根結點,A和C做爲子結點
插入D
插入E
插入元素時,若是樹結構不知足B樹的性質時,就會進行合併或分裂
B樹與二叉樹的比較
下面使用元素相同的平衡二叉樹(二叉樹裏面查詢快)與B樹的查詢做比較
平衡二叉樹查詢 H
第一步
第二步
第三步
第四步
B樹查詢 H
第一步
第二步
第三步
第四步
雖然看上去都是須要四步才能完成H的查詢,由於樹結構是非線性的,每一個結點的地址是不連續的,因此B樹的第四步是在一塊內存內比較,要比平衡二叉樹的第四步從新尋找地址快不少,而且,若是數據是存放在磁盤而不是內存的時候,每次IO操做性能消耗很是大,且隨着數據量增大,二者的性能差距更加明顯
B+樹
B+樹與B樹的區別在於B+樹每個元素都存在於葉子結點,非葉子結點僅僅提供索引操做,必須到葉子結點纔會命中
這樣保證了咱們尋找任意一個元素時,所須要的時間都是同樣的
而且葉子結點以鏈表形式鏈接,這樣有利於遍歷全部數據時候,只須要進行線性查詢,而不用一層一層遍歷