SBT(Size Balanced Tree)
阿新 • • 發佈:2018-11-21
表示 oid 情況 行高 tree 隨機 tar div 復雜
1. 二叉搜索樹
二叉搜索樹,是一種能實現動態查詢第k大或查詢,某數在序列中的排名的樹形結構,在數據較為隨機的情況下,它的期望復雜度為O(logn),但是若是數據為一個有序序列,那麽該二叉搜索樹,將會變成一條鏈,此時每次查找的復雜度將會變成復雜度為O(n)
2. SBT
針對上述問題,為了能使復雜度回到O(logn),我們在每次插入操作後,對樹形進行高效的調整使之變的較為平衡。這時樹高變成logn 而搜索的復雜度也於是會變回logn為此我們引入左旋和右旋操作
void zx(int &x) { int y=rs[x]; rs[x]=ls[y]; ls[y]=x; siz[y]=siz[x]; siz[x]=siz[ls[x]]+siz[rs[x]]+1; x=y; }
void yx(int &x) { int y=ls[x]; ls[x]=rs[y]; rs[y]=x; siz[y]=siz[x]; siz[x]=siz[ls[x]]+siz[rs[x]]+1; x=y; }
為了能使樹更加平衡,我們規定該點的左兒子不可以比該點的右兒子的左兒子和右兒子大,用代碼表示起來就是siz[rs[rs[now]]]<=siz[ls[now]]和siz[ls[rs[now]]]<=siz[ls[now]],同理該點的右兒子不可以比該點的左兒子的左兒子和右兒子大。
為了達到這個目的,我們進行一個maintain操作,對不平衡的子樹進行調整(註:雖然它的復雜度看起來似乎是O(n)但實際上它的復雜度是O(1)的)
void maintain(int &now,int how) { if(how) { if(siz[rs[rs[now]]]>siz[ls[now]]) zx(now); else if(siz[ls[rs[now]]]>siz[ls[now]]) yx(rs[now]),zx(now); else return; }else { if(siz[ls[ls[now]]]>siz[rs[now]]) yx(now); else if(siz[rs[ls[now]]]>siz[rs[now]]) zx(ls[now]),yx(now); else return; } maintain(ls[now],0); maintain(rs[now],1); maintain(now,0); maintain(now,1); }
接下來的操作都是二叉搜索樹的操作了,加點操作較為簡單,不再贅述
SBT(Size Balanced Tree)