Size Balanced Tree
??Size Balanced Tree(SBT)是目前速度最快的平衡二叉搜索樹(shù),且能夠進(jìn)行多種搜索操作,區(qū)間操作;和AVL、紅黑樹(shù)、伸展樹(shù)、Treap類似,SBT也是通過(guò)對(duì)節(jié)點(diǎn)的旋轉(zhuǎn)來(lái)維持樹(shù)的平衡,而相比其他平衡樹(shù),SBT維持平衡所需要的額外數(shù)據(jù)很少,只需要維持以當(dāng)前節(jié)點(diǎn)為根的子樹(shù)的大小;且SBT的編寫(xiě)復(fù)雜度低。因此具有空間優(yōu)勢(shì)、速度優(yōu)勢(shì)、編寫(xiě)優(yōu)勢(shì)。
SBT的節(jié)點(diǎn)
????SBT節(jié)點(diǎn)維持很少的額外信息,只需要知道以當(dāng)前節(jié)點(diǎn)為根的子樹(shù)的大小。
struct TreeNode{int data;TreeNode* child[2];int size; //以該節(jié)點(diǎn)為根的子樹(shù)的大小(節(jié)點(diǎn)的個(gè)數(shù))TreeNode(int d){data = d;child[0] = child[1] = NULL;size = 1;}};?
SBT的平衡性質(zhì)
????一棵平衡的SBT樹(shù)滿足如下要求:
????記S[t]為以節(jié)點(diǎn)t為根的子樹(shù)的大小,則對(duì)于每個(gè)節(jié)點(diǎn)T,記其左子節(jié)點(diǎn)L, 右子節(jié)點(diǎn)R, 左子結(jié)點(diǎn)的左子結(jié)點(diǎn)LL, 左子結(jié)點(diǎn)的右子節(jié)點(diǎn)LR, 右子節(jié)點(diǎn)的左子結(jié)點(diǎn)RL, 右子節(jié)點(diǎn)的右子節(jié)點(diǎn)RR。?
????則有, S[L] >= max(S[RL], S[RR]), S[R] >= max(S[LL], S[LR]).?
即任何一個(gè)節(jié)點(diǎn)的size均大于等于其侄子節(jié)點(diǎn)的size。?(侄子節(jié)點(diǎn):定義為一個(gè)節(jié)點(diǎn)的兄弟節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn))
SBT的維護(hù)操作
????一棵平衡的SBT在進(jìn)行插入和刪除之后,可能會(huì)不再平衡,此時(shí)需要進(jìn)行維護(hù)操作,維護(hù)操作需要進(jìn)行左旋或者右旋操作,旋轉(zhuǎn)操作和其他平衡樹(shù)的旋轉(zhuǎn)類似(具體見(jiàn)zig-zag旋轉(zhuǎn)) .?
????SBT的非平衡情況分為兩類:左子結(jié)點(diǎn)和左子結(jié)點(diǎn)的侄子節(jié)點(diǎn)不平衡或者右子節(jié)點(diǎn)和右子節(jié)點(diǎn)的侄子節(jié)點(diǎn)不平衡。這里以右子節(jié)點(diǎn)和右子節(jié)點(diǎn)的侄子節(jié)點(diǎn)為例,進(jìn)行Maintain操作。?
????失衡情形1:????S[LL] > S[R]?
?
(1)執(zhí)行 RightRotate(T),得到如下結(jié)果?
?
(2)此時(shí)以T為根的樹(shù)可能不平衡,遞歸調(diào)用Maintain(T)?
?
(3)此時(shí)T成為平衡SBT, 再次對(duì)L調(diào)用Maintain(L)將整體變?yōu)槠胶釹BT?
????失衡情形2:????S[LR] > S[R]?
?
(1)執(zhí)行 LeftRotate(L),得到如下結(jié)果?
?
(2)執(zhí)行 RightRotate(T),得到如下結(jié)果?
?
(2)此時(shí)以B和R為根的樹(shù)可能不平衡,遞歸調(diào)用Maintain(B)、Maintain(R)?
?
(3)此時(shí)T成為平衡SBT, 再次對(duì)L調(diào)用Maintain(L)將整體變?yōu)槠胶釹BT?
????由于Maintain操作是個(gè)遞歸執(zhí)行的函數(shù),貌似可能會(huì)出現(xiàn)無(wú)限循環(huán),但實(shí)際上,陳啟峰在論文里分析過(guò)了,Maintain操作的平坦復(fù)雜度為O(1)。因此Maintain操作不會(huì)出現(xiàn)無(wú)法結(jié)束的情況。
SBT的其他操作
????和其他的二叉搜索樹(shù)一樣,SBT支持插入、刪除、查找等操作。插入和刪除操作可能會(huì)破壞SBT的平衡性質(zhì),因此,需要在普通的插入和刪除之后對(duì)節(jié)點(diǎn)進(jìn)行維護(hù),即調(diào)用Maintain函數(shù)。
實(shí)現(xiàn)(c++)
#include<iostream> using namespace std; struct TreeNode{int data;TreeNode* child[2];int size;int count;TreeNode(int d){data = d;child[0] = child[1] = NULL;size = count = 1;}void Update(){size = count;if (child[0]){size += child[0]->size;}if (child[1]){size += child[1]->size;}} }; struct SBT{TreeNode* root;SBT() :root(NULL){};void Rotate(TreeNode*& node, int dir){TreeNode* ch = node->child[dir];node->child[dir] = ch->child[!dir];ch->child[!dir] = node;node = ch;}//返回node節(jié)點(diǎn)為根的子樹(shù)的大小int GetSize(TreeNode* node){if (node)return node->size;return 0; //對(duì)于空節(jié)點(diǎn),直接返回0}//維持平衡void Maintain(TreeNode*& node, bool flag){TreeNode* R = node->child[1];TreeNode* L = node->child[0];TreeNode* LL = NULL,*LR = NULL,*RL = NULL,*RR = NULL;if (L){LL = L->child[0];LR = L->child[1];}if (R){RL = R->child[0];RR = R->child[1];}if (flag == false){ //左邊維護(hù)if (GetSize(LL) > GetSize(R)){ //失衡情況1 Rotate(node, 0);}else if (GetSize(LR) > GetSize(R)){ //失衡情況2Rotate(L, 1);Rotate(node, 0);}else{return; //不失衡,直接返回}}else{if (GetSize(RR) > GetSize(L)){Rotate(node, 1);}else if (GetSize(RL) > GetSize(L)){Rotate(R, 0);Rotate(node, 1);}else{return;}}Maintain(node->child[0], false); //繼續(xù)將 左子樹(shù)維持平衡,注意這里不能直接使用L,因?yàn)橹斑M(jìn)行了旋轉(zhuǎn)操作Maintain(node->child[1], true); //繼續(xù)將 右子樹(shù)維持平衡Maintain(node, true); //再維持 nodeMaintain(node, false); }void Insert(TreeNode*& node, int data){if (!node){node = new TreeNode(data);return;}else if (node->data == data){node->count++;node->Update(); //更新本節(jié)點(diǎn)以及其祖先節(jié)點(diǎn)的sizereturn;}else {int dir = node->data < data;Insert(node->child[dir], data);Maintain(node, ! dir); //如果新插入的數(shù)據(jù) 小于 當(dāng)前節(jié)點(diǎn)的數(shù)據(jù),則被插入左子樹(shù),//此時(shí)左子樹(shù)的左右子節(jié)點(diǎn)的size可能大于右子節(jié)點(diǎn),因此Maintain(x, false)node->Update();} }void Delete(TreeNode*& node, int w){if (!node){return;}if (node->data == w){if (node->child[0] && node->child[1]){TreeNode* succ = node->child[1];while (succ->child[0]){succ = succ->child[0];}node->data = succ->data;succ->data = w;Delete(node, w);}else{TreeNode* tmp_node = NULL;if (node->child[0])tmp_node = node->child[0];elsetmp_node = node->child[1];delete node;node = tmp_node;}}Maintain(node, false);node->Update();}};?參考:?
SBT-陳啟峰
?
轉(zhuǎn)載于:https://www.cnblogs.com/gtarcoder/p/4724288.html
總結(jié)
以上是生活随笔為你收集整理的Size Balanced Tree的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: AsyncTask理解- Day36or
- 下一篇: JAVA第二周。