手写一个节点大小平衡树(SBT)模板,留着用
2015-08-13 19:03
260 查看
看了一下午,感觉有了些了解,应该没有错,有错希望斧正,感谢
#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; }
相关文章推荐
- 斯坦福ML公开课笔记15—隐含语义索引、奇异值分解、独立成分分析
- 求无向图的割点 (poj 1144 Network)
- [转载] 从Hadoop到Spark的架构实践
- 求无向图的割点 (poj 1144 Network)
- Hadoop相关基础知识
- mac os 下的sublime --- 快捷键
- HDU_4731 Minimum palindrome(找规律)
- 深入理解java的finalize
- 斯坦福ML公开课笔记14——主成分分析
- hdu3695(AC自动机)
- Eclipse ADT的Custom debug keystore所需证书规格
- laravel 5 sentinel(权限管理包)安装笔记
- SOAPUI 数据源设置
- Mongdb安全和认证
- VS2005调节主界面时,界面上的控件,以及(tab control中的)子界面上的控件一起缩放
- Oracle 学习之RAC(六) 安装数据库
- [转]C/C++中的memset
- 简单的String类
- POJ 2075 Tangled in Cables 最小生成树 Kruskal && Prim
- 斯坦福ML公开课笔记13B-因子分析模型及其EM求解