1. 程式人生 > 其它 >替罪羊樹——簡單粗暴的資料結構

替罪羊樹——簡單粗暴的資料結構

替罪羊樹——簡單粗暴的資料結構
正題
如果在一棵平衡的二叉搜尋樹內進行查詢等操作,時間就可以穩定在log(n),但是每一次的插入節點和刪除節點,都可能會使得這棵樹不平衡,最壞情況就是退化成一條鏈,顯然我們不想要這種樹,於是各種維護的方法出現了,大部分的平衡樹都是通過旋轉來維護平衡的,但替罪羊樹就很厲害了,一旦發現不平衡的子樹,立馬拍扁重建,這就是替罪羊樹的核心:暴力重建
lc,rc分別表示i的左右子樹
對以p為根的子樹重構當且僅當
siz[lc]>siz[p]*alpha
或者
siz[rc]>siz[p]*alpha
alpha(∈[0.5,1])alpha(∈[0.5,1])是自己設定的一個引數,規定了這棵樹的平衡程度
當alpha==0.5alpha==0.5時,幾乎每次都要重構,樹為平衡樹,但是重構次數太多
當alpha==1.0alpha==1.0時,不會重構,此時是普通的二叉搜尋樹,有可能卡成鏈
重構方法:先對以p為根的子樹DFS(中序遍歷),將序號存在一個數組裡。因為是中序遍歷,因此陣列內點的值是有序的,可以直接build
重構操作
首先將要重構的子樹拍平(遍歷一次得到一個數組),然後利用這個陣列進行重構。每次的節點為這個區間的中點,然後遞迴呼叫去把[l, mid - 1]重構左子樹,[mid + 1, r]重構有子樹。記得在每層函式返回之前進行子樹大小的維護。
首先中序遍歷得到一個有序的陣列(由於我比較懶,所以用的vector,建議儲存節點的地址或下標,不要只儲存資料)
找到mid,然後遞迴生成它的左子樹和右子樹:
為了體現當l > r時,直接return NULL