JAVA对SBTree(size blanced tree)的实现尝试

本文详细介绍了如何使用Java实现并优化SBTree数据结构。包括代码实现、问题解决、性能提升等方面,旨在提高数据结构的效率与实用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

尽管不明白用java写数据结构的好处究竟有多大,但是了解了SBTree之后我就想尝试着去实现。最终做出了一个不规范的类似物。

希望大触们的意见!

下面的是带着草稿的源码。

package SBTree;
import java.util.ArrayList;
public class SBTree<UnknownType extends Comparable<UnknownType>>{
    public int capacity=0;
    private SBTreeNode NIL=new SBTreeNode(-1,null);
    private int head=-1;
    public int size=0;
    private ArrayList<SBTreeNode> root;
    public SBTree(){
        root=new ArrayList<SBTreeNode>();
        NIL.size=0;
    }
    @Override
    public String toString(){
        return "size="+this.size+",capacity="+this.capacity+"\r\n"+this.root.toString();
    }
    //重写的toString方法
    private SBTreeNode get(int index){
        if(index==-1) return NIL;
        return this.root.get(index);
    }//对节点返回的内部方法,index为-1时返回NIL值,其余则与ArrayList相同
    public UnknownType getValue(int index){
        return this.get(index).value;
    }
    //返回节点值,index为-1时返回null值,其余则与ArrayList相同
    private void leftRotate(int index){
        if(index==-1) return;
        SBTreeNode leftone=this.get(index);
        if(leftone.right==-1) {System.out.println("error");return;}
        //System.out.println(leftone);
        SBTreeNode rightone=this.get(leftone.right);
        leftone.right=rightone.left;
        this.get(rightone.left).parent=leftone.index;
        rightone.left=index;
        leftone.size-=1+this.get(rightone.right).size;
        rightone.size+=1+this.get(leftone.left).size;
        if(index!=this.head){
            if(leftone.index==this.get(this.get(leftone.parent).left).index)
                this.get(leftone.parent).left=rightone.index;
            else     this.get(leftone.parent).right=rightone.index;
        }
        else this.head=rightone.index;
        rightone.parent=leftone.parent;
        leftone.parent=rightone.index;
        //System.out.println(leftone);
    }//树的左旋
    private void rightRotate(int index){
        if(index==-1) return;
        SBTreeNode rightone=this.get(index);
        if(rightone.left==-1) {System.out.println("error");return ;}
        //System.out.println(rightone);
        SBTreeNode leftone=this.get(rightone.left);
        rightone.left=leftone.right;
        this.get(leftone.right).parent=rightone.index;
        leftone.right=index;
        rightone.size-=1+this.get(leftone.left).size;
        leftone.size+=1+this.get(rightone.right).size;
        if(this.get(rightone.parent).index!=-1){
            if(rightone.index==this.get(this.get(rightone.parent).right).index)
                this.get(rightone.parent).right=leftone.index;
            else this.get(rightone.parent).left=leftone.index;
        }
        else this.head=leftone.index;
        leftone.parent=rightone.parent;
        rightone.parent=leftone.index;
        //System.out.println(rightone);
    }//树的右旋
    private void maintain(int index){
        if(index==-1) return;
        SBTreeNode leftone=this.get(this.get(index).left);
        SBTreeNode rightone=this.get(this.get(index).right);
        if(this.get(leftone.left).size>rightone.size){
            rightRotate(index);
            maintain(leftone.right);
            maintain(leftone.index);
        }
        if(this.get(leftone.right).size>rightone.size){
            leftRotate(leftone.index);
            rightRotate(index);
            maintain(leftone.left);
            maintain(leftone.right);
            maintain(leftone.index);
        }
        if(this.get(rightone.right).size>leftone.size){
            leftRotate(index);
            maintain(rightone.left);
            maintain(rightone.index);
        }
        if(this.get(rightone.right).size>leftone.size){
            rightRotate(rightone.index);
            leftRotate(index);
            maintain(rightone.right);
            maintain(rightone.left);
            maintain(rightone.index);
        }
    }//特别的SBTree的maintain操作
    /*private void maintain(int index,boolean flag){
        if(index==-1) return;
        SBTreeNode leftone=this.get(this.get(index).left);
        SBTreeNode rightone=this.get(this.get(index).right);
        if(!flag){
            if(this.get(leftone.left).size>rightone.size)
                rightRotate(index);
            if(this.get(leftone.right).size>rightone.size){
                leftRotate(leftone.index);
                rightRotate(index);
            }
        }
        if(flag){
            if(this.get(rightone.right).size>leftone.size)
                leftRotate(index);
            if(this.get(rightone.right).size>leftone.size){
                rightRotate(rightone.index);
                leftRotate(index);
            }
        }
        maintain(leftone.index,false);
        maintain(leftone.index,true);
        maintain(index,false);
        maintain(index,true);
    }//特别的优化的maintain操作*/
    public boolean add(UnknownType value){
        SBTreeNode newNode=new SBTreeNode(this.capacity,value),result=null;
        if(!this.root.add(newNode)) return false;
        else{
            this.size++;
            this.capacity++;
            if(this.head==-1) this.head=newNode.index;
            else{
                int search=this.head,flag=1;
                while(search!=-1){
                    result=this.get(search);
                    if((flag=value.compareTo(result.value))>0) search=result.right;
                    else search=result.left;
                    result.size++;
                }
                if(flag>0) result.right=newNode.index;
                else result.left=newNode.index;
                newNode.parent=result.index;
                for(search=newNode.index;search!=-1;search=this.get(search).parent)
                    this.maintain(search);
                //for(search=newNode.index;search!=this.head;search=this.get(search).parent)    
                    //this.maintain(search,this.get(search).value.compareTo(this.get(this.get(search).parent).value)>0);
            }
            //this.print_r();
            return true;
        }
    }
    //树的插入操作,成功返回true,失败返回false
    private void printr(int index,int floor){
        if(index==-1) return ;
        System.out.println(floor+" floor: "+this.get(index));
        printr(this.get(index).left,floor+1);
        printr(this.get(index).right,floor+1);
    }//内部对每个子树的打印递归方法
    public void print_r(){
        System.out.println("************************");
        printr(this.head,0);
        System.out.println("************************");
    }
    private void prints(int index,int floor){
        if(index==-1) return ;
        prints(this.get(index).left,floor+1);
        System.out.println(floor+" floor: "+this.get(index));
        prints(this.get(index).right,floor+1);
    }//内部对每个子树的打印递归方法2
    private void print(int index,int floor){
        if(index==-1) return ;
        print(this.get(index).right,floor+1);
        System.out.println(floor+" floor: "+this.get(index));
        print(this.get(index).left,floor+1);
    }//内部对每个子树的打印递归方法3
    //直接打印该树,中序遍历。
    public void print_s(boolean flag){
        System.out.println("************************");
        if(flag) prints(this.head,0);
        else print(this.head,0);
        System.out.println("************************");
    }
    //直接打印该树,true为顺序,false为倒序。
    public int searchByValue(UnknownType value){
        for(int search=this.head;search!=-1;){
            int flag=value.compareTo(this.get(search).value);
            if(flag>0) search=this.get(search).right;
            else if(flag<0) search=this.get(search).left;
            else return search;
        }
        return -1;
    }
    //返回该树中某一个值与其相等的节点index,否则为-1。
    public int searchBySequence(int index){
        int flag=this.size;
        for(int search=this.head;search!=-1;){
            SBTreeNode result=this.get(search);
            flag=index-this.get(result.left).size;
            if(flag<=0) search=result.left;
            else if(flag==1) return search;
            else{
                search=result.right;
                index=flag;
            }
        }
        return -1;
    }
    //返回该树中第i小的节点index,否则为-1。
    public boolean exists(int index){
        if(this.capacity<index || this.root.get(index).index!=index) return false;
        else return true;
    }//分辨是否为碎片节点。
    public void adjust(){
        System.out.println("adjusted when rate="+(double)this.size/this.capacity);
        int j=0;
        for(int i=this.capacity-1;i>j;i--){
            if(this.exists(i)){
                for(;i>j;j++)
                    if(!this.exists(j)){
                        SBTreeNode result=this.get(i);
                        this.get(result.left).parent=j;
                        this.get(result.right).parent=j;
                        if(i==this.head) this.head=j;
                        else{
                            if(this.get(result.parent).left==i) this.get(result.parent).left=j;
                            else if(this.get(result.parent).right==i) this.get(result.parent).right=j;
                            else System.out.println("wrong when i="+i+" j="+j);
                        }
                        result.index=j;
                        this.root.set(j++,result);
                        this.root.remove(i);
                        this.capacity--;
                        break;
                }
            }
            else{
                this.root.remove(i);
                this.capacity--;
            }
        }
    }//碎片整理函数,必要时调用。
    private boolean deleteByIndex(int index){
        SBTreeNode deleting=this.get(index);
        if(index<0 || deleting==null || deleting==NIL) return false;
        else {
            int parent=deleting.parent;
            while(deleting.left!=-1 || deleting.right!=-1){
                if(this.get(deleting.left).size>this.get(deleting.right).size) this.rightRotate(index);
                else this.leftRotate(index);
            }
            if(this.get(deleting.parent).left==index) this.get(deleting.parent).left=-1;
            else if(this.get(deleting.parent).right==index) this.get(deleting.parent).right=-1;
            else System.out.println("fault");
            for(SBTreeNode result=deleting;result.index!=-1;result=this.get(result.parent))
                result.size--;
            for(;deleting.index!=parent;deleting=this.get(deleting.parent))
                maintain(deleting.index);
            maintain(parent);
            this.root.set(index,NIL);
            deleting=null;
            this.size--;
            return true;
        }
    }//删除节点的内部方法
    public boolean deleteByIndex(int index,boolean flag){
        if(flag) this.adjust();
        return deleteByIndex(index);
    }
    //flag为true时进行adjust整理。false则不进行。
    //将节点index为index的节点删除,重复删除返回false。
    public boolean deleteBySequence(int i,boolean flag){
        if(flag) this.adjust();
        return deleteByIndex(this.searchBySequence(i));
    }
    //flag为true时进行adjust整理。false则不进行。
    //将节点大小排名为i的节点删除,重复删除返回false。
    public int size(){
        return this.size;
    }
    //获得size值
    class SBTreeNode{
        int index;
        int size=1;
        int left=-1;
        int right=-1;
        int parent=-1;
        UnknownType value=null;
        @Override
        public String toString(){
            if(this.value==null) return "NULL NODE";
            else return this.index+":"+this.value.toString()+" (which has "+this.size+" node parent is node "+this.parent+" )";
        }
        public SBTreeNode(int index,UnknownType value){
            this.index=index;
            this.value=value;
        }
    }
}


写完初步运行尚可,问题是:

NIL设置成静态常量会报错。(jdk8)

另外maintain方法用的是效率低的那种。

还有UnknownType写成没有实现Comparable接口的会怎么样没有试过

最后还有问题,就是假如节点的left和right设置成节点类型还是int靠tree检索好不清楚

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值