手寫一個節點大小平衡樹(SBT)模板,留著用
阿新 • • 發佈:2019-02-11
看了一下午,感覺有了些瞭解,應該沒有錯,有錯希望斧正,感謝
#include<stdio.h> #include<string.h> struct s { int key,left,right,size; }tree[10010]; int top; void left_rot(int &x)// 左旋 { int y=tree[x].right; tree[x].right=tree[y].left; tree[y].left=x; tree[y].size=tree[x].size; tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1; x=y; } void right_rot(int &x)//右旋 { int y=tree[x].left; tree[x].left=tree[y].right; tree[y].right=x; tree[y].size=tree[x].size; tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1; x=y; } void maintain(int &x,bool flag)//維護SBT狀態 { if(flag==false)//左邊 { if(tree[tree[tree[x].left].left].size>tree[tree[x].right].size)//左孩子的左孩子大於右孩子 right_rot(x); else if(tree[tree[tree[x].left].right].size>tree[tree[x].right].size)//左孩子的右孩子大於右孩子 { left_rot(tree[x].left); right_rot(x); } else return; } else//右邊 { if(tree[tree[tree[x].right].right].size>tree[tree[x].left].size)//右孩子的右孩子大於左孩子 left_rot(x); else if(tree[tree[tree[x].right].left].size>tree[tree[x].left].size)//右孩子的左孩子大於左孩子 { right_rot(tree[x].right); left_rot(x); } else return; } maintain(tree[x].left,false); maintain(tree[x].right,true); maintain(x,true); maintain(x,false); } void insert(int &x,int key)//插入 { if(x==0) { x=++top; tree[x].left=0; tree[x].right=0; tree[x].size=1; tree[x].key=key; } else { tree[x].size++; if(key<tree[x].key) insert(tree[x].left,key); else insert(tree[x].right,key);//相同元素可插右子樹 maintain(x,key>=tree[x].key); } } int remove(int &x,int key)//利用後繼刪除 { tree[x].size--; if(key>tree[x].key) remove(tree[x].right,key); else if(key<tree[x].key) remove(tree[x].left,key); else if(tree[x].left!=0&&tree[x].right==0)//有左子樹,無右子樹 { int temp=x; x=tree[x].left; return temp; } else if(!tree[x].left&&tree[x].right!=0)//有右子樹,無左子樹 { int temp=x; x=tree[x].right; return temp; } else if(!tree[x].left&&!tree[x].right)//無左右子樹 { int temp=x; x=0; return temp; } else//左右子樹都有 { int temp=tree[x].right; while(tree[temp].left) temp=tree[temp].left; tree[x].key=tree[temp].key; remove(tree[x].right,tree[temp].key); } } int getmin(int x)//求最小值 { while(tree[x].left) x=tree[x].left; return tree[x].key; } int getmax(int x)//求最大值 { while(tree[x].right) x=tree[x].right; return tree[x].key; } int pred(int &x,int y,int key)//前驅,y初始前驅,從0開始, 最終要的是返回值的key值 { if(x==0) return y; if(key>tree[x].key) return pred(tree[x].right,x,key); else return pred(tree[x].left,y,key); } int succ(int &x,int y,int key)//後繼,同上 { if(x==0) return y; if(key<tree[x].key) return succ(tree[x].left,x,key); else return succ(tree[x].right,y,key); } int select(int &x,int k)//選第k小的數 { int r=tree[tree[x].left].size+1; if(r==k) return tree[x].key; else if(r<k) return select(tree[x].right,k-r); else return select(tree[x].left,k); } int rank(int &x,int key)//key排第幾 { if(key<tree[x].key) { return rank(tree[x].left,key); } else if(key>tree[x].key) return rank(tree[x].right,key)+tree[tree[x].left].size+1; else return tree[tree[x].left].size+1; } void order(int &x) { if(x==0) return; order(tree[x].left); printf("%d\n",tree[x].key); order(tree[x].right); } int main() { top=0; }