zoukankan      html  css  js  c++  java
  • 手写一个节点大小平衡树(SBT)模板,留着用

    看了一下午,感觉有了些了解。应该没有错,有错希望斧正,感谢

    #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
    ",tree[x].key);
    	order(tree[x].right);
    }
    int main()
    {
    	top=0;
    }


  • 相关阅读:
    三剑客
    走近SQL Server的游标
    PostSharp的AOP设计在.NET Remoting中的应用
    总结在使用VB 6.0和C#编写ActiveX控件的实践 (一)
    动态为程序指定快捷键
    为Reporting Service部署自定义程序集可能遇到的问题
    如何更改服务器名称
    如何产生固定的随机数(VBA)
    使用HTTP发送消息(消息队列技术)
    使用TransactionScope做分布式事务协调
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7027642.html
Copyright © 2011-2022 走看看