0
点赞
收藏
分享

微信扫一扫

二叉排序树

秦瑟读书 2022-04-27 阅读 68
java
package mylearn;
public class binarysorttree {
    private dot root;
    public void add(dot d)
    {
        if(root==null)//核心,当root空时就直接把第一个add的作为root,这样就能调用indexorder
        {
            this.root=d;
        }else{this.root.add(d);}
    }
    public void indexorder()
    {
        if(root==null)
        {
            return;
        }else{this.root.indexorder();}
    }
    //封装一下查找删除节点和父节点的方法
    public dot searchwantdel(int value)
    {
        if(root==null)
        {
            return null;
        }else{  return this.root.search(value);}
    }
    public dot searchfatherdot(int value)
    {
        if(root==null)
        {
            return null;
        }else{ return this.root.searchfather(value);}
    }
    public void deldot(int value)
    {
        if(root==null){return;}
        dot target=searchwantdel(value);
        dot father=searchfatherdot(value);
        System.out.println("目标节点"+target+"父节点"+father);
        if(target==null){return ;}//没找到要删除节点
        if(root.left==null&&root.right==null){ root=null;}//发现树只有个根节点
        //target是叶子节点时,看target是father左子节点还是右子节点
        if(father!=null)//避免空指针
        {
            if(target.left==null&&target.right==null&&father.left==target){father.left=null;}//当是father左子节点
            if(target.left==null&&target.right==null&&father.right==target){father.right=null;}//当是father左子节点
        }
        if(father==null)//当father=null时还用上面代码会出现空指针异常/father=null相当于target=root直接让左或右的叶子节点为root
        {
            if(target.left!=null&&target.right==null){root=target.left;}
            if(target.right!=null&&target.left==null){root=target.right;}
        }
        if(target.left!=null&&target.right!=null)//第二种情况左右子树都有 找右子树最小节点由temp保存,删除此最小节点,并且target.value=temp.value//是改值不是改节点!!!
        {
            dot RighttreeMin=delRightTreeMin(target.right);
            target.value=RighttreeMin.value;
        }
        if((target.left==null&&target.right!=null&&father!=null)||(target.left!=null&&target.right==null&&father!=null))//第三种情况只有一边有子树
        {
            if(father.left==target&&target.left!=null)
                {
                    father.left=target.left;
                }
                if(father.left==target&&target.right!=null)
                {
                    father.left=target.right;
                }
                if(father.right==target&&target.left!=null)
                {
                    father.right=target.left;
                }
                else
                {
                    father.right=target.right;
                }
        }
        if((target.left==null&&target.right!=null&&father==null)||(target.left!=null&&target.right==null&&father==null))
        {
            if(target.left!=null){root=target.left;}
            if(target.right!=null){root=target.right;}
        }

    }
    public dot delRightTreeMin(dot targetright)//一直往左找找的最小
    {
        dot temp=targetright;
        while(temp.left!=null)
        {
            temp=temp.left;
        }
        deldot(temp.value);//删除最小节点
        return temp;
    }

//main调试
    public static void main(String[] args) {
        int []arr={1,3,5,7,9,10,12};
        binarysorttree tree1=new binarysorttree();
        for(int i=0;i<arr.length;i++)
        {
            tree1.add(new dot(arr[i]));//添加时就创建
        }
        tree1.indexorder();
        System.out.println("search");
        System.out.println("67的父节点"+tree1.searchfatherdot(7));
        System.out.println(tree1.searchwantdel(7));
//        System.out.println("删除叶子节点");
//        tree1.deldot(8);
//        tree1.deldot(7);
//        tree1.deldot(3);
//        tree1.indexorder();
        tree1.deldot(2);
        tree1.deldot(5);
        tree1.deldot(9);
        tree1.deldot(12);
        tree1.deldot(7);
        tree1.deldot(3);
        tree1.deldot(10);
        tree1.deldot(1);
        tree1.indexorder();

    }
}
class dot {
    @Override
    public String toString() {
        return "value" + this.value;
    }

    int value;
    dot left;
    dot right;

    public dot(int value) {
        this.value = value;
    }

    public void add(dot d) {
        if (d.value < this.value)
        {
            if (this.left == null)
            {
                this.left = d;
            }
            else
            {
                this.left.add(d);
            }
        }
        else //大于等于放右子树
        {
            if (this.right == null)
            {
                this.right = d;
            }
            else
            {
                this.right.add(d);
            }
        }
    }

    public void indexorder() {
        if (this.left != null) {
            this.left.indexorder();
        }
        System.out.println(this);
        if (this.right != null) {
            this.right.indexorder();
        }
    }
    public dot search(int value)
    {
        if(value == this.value)
        {
            return this;
        }
        else if(value < this.value)
        {
            if(this.left  == null)
            {
                return null;
            }
            return this.left.search(value);
        }
        else
        {
            if(this.right == null)
            {
                return null;
            }
            return this.right.search(value);
        }

    }

    public dot searchfather(int value) {
        if ((this.left != null && this.left.value == value) || (this.right != null && this.right.value == value))//!=null为了避免空指针异常
        {
            return this;
        }
        else
        {
            if (value < this.value )
            {
                if(this.left==null){return null;}
                return this.left.searchfather(value);
            }
            else if (value >= this.value )
            {
                if(this.right==null) {return null;}
                return this.right.searchfather(value);
            }
        } return null;
    }
}

使用数组

数组未排序 优点:直接在尾部添加,速度快。缺点:查找速度慢

数组排序 优点:可以用二分查找法 查找速度快 缺点:为保证数组有序 在添加新数据时,快速找到添加位置,但是后面的数要整体后移,速度慢。

使用链表

不管链表是否有序,查找速度都慢,添加数据比数组快,不需要整体后移

使用二叉排序树 不管添加还是查找都快 

举报

相关推荐

0 条评论