数据结构-二叉树-二叉搜索树

一、什么是二叉搜索树

二叉搜索树本质还是二叉树,但它在不空时添加节点,它左子树上所有的元素都小于根节点的元素,而根节点右子树上所有的元素都大于根节点的元素。
通过以上方法建的树的中序遍历是从小到大的序列,所以二叉搜索树又称之为二叉排序树。
在这里插入图片描述

二、二叉搜索树的基本操作

2.1二叉搜索树插入节点

由于二叉搜索树仍然是二叉树,所以先建立二叉树类

public class tree {
    private Object data;
    private tree left;
    private tree right;

    public tree (){}
    public tree(Object data) {
        this.data = data;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public tree getLeft() {
        return left;
    }

    public void setLeft(tree left) {
        this.left = left;
    }

    public tree getRight() {
        return right;
    }

    public void setRight(tree right) {
        this.right = right;
    }
}

接下来就是如何在二叉搜索树中添加节点
1.非递归的方式添加节点
(1)思路首先建立一个二叉树,如果根节点为空,则将新建的二叉树地址传给跟根节点。如果不为空进行(2)
(2)建立临时节点取得根节点,当临时节点不为空时,判断根节点和当前新建的树要比较值的大小(这里建立的二叉树储存的值的类型为Object,所以取出的数据需要连接Comparalbe接口),如果新节点小于当前节点,那么进行(3),如果新节点不小于当前节点,进行(4)
(3)判断临时节点的左子树是否为空,如果为空将新节点设置为临时节点的左子树,添加完毕退出循环。如果不为空,临时节点指向它的左子树,返回(2)
(4)判断临时节点的右子树是否为空,如果为空将新节点设置为临时节点的右子树,添加完毕退出循环。如果不为空,临时节点指向它的右子树,返回(2)

public void add (Object data){
        tree t = new tree(data);
        if(root == null){
            root = t;
        }else {
            tree temp = root;
            while(temp!=null){
                Comparable comparable =(Comparable)temp.getData();
                if(comparable.compareTo(data)==1){
                    if(temp.getLeft()!=null)
                        temp = temp.getLeft();
                    else {
                        temp.setLeft(t);
                        break;
                    }
                }
                else {
                    if (temp.getRight() != null)
                        temp = temp.getRight();
                    else {
                        temp.setRight(t);
                        break;
                    }
                }
            }
        }
        this.size++;
    }

2.递归的方式添加节点
思路:
(1)思路首先建立一个二叉树,如果根节点为空,则将新建的二叉树地址传给跟根节点。如果不为空进行(2)
(2)建立函数f(tree currentNode,tree newNode) 两个参数表示当前临时节点和新节点。将这两个节点进行比较如果新节点小于当前节点,那么进行(3),如果新节点不小于当前节点,进行(4)
(3)判断当前节点的左子树是否为空,如果为空将新节点设置为临时节点的左子树,添加完毕。如果不为空,调用f(tree currentNode,tree newNode) 将当前currentNode修改为currentNode.getLeft().
(4)判断临时节点的右子树是否为空,如果为空将新节点设置为临时节点的右子树,添加完毕。如果不为空,如果不为空,调用f(tree currentNode,tree newNode) 将当前currentNode修改为currentNode.getRight().

public void diguiAdd(Object data){
        boolean flag = false;
        tree node = new tree(data);
        if(root == null){
            root = node;
        }
        else{
            flag = f(this.root,node);
        }
        if(!flag)
            this.size++;
    }

    private boolean f(tree currentNode,tree newNode){
        Comparable c = (Comparable) currentNode.getData();
        Comparable n = (Comparable) newNode.getData();
        if(c.compareTo(n) == -1){
            if(currentNode.getRight() != null){
                f(currentNode.getRight(),newNode);
            }else{
                currentNode.setRight(newNode);
            }
        }else if(c.compareTo(n) == 1){
            if(currentNode.getLeft() != null){
                f(currentNode.getLeft(),newNode);
            }else{
                currentNode.setLeft(newNode);
            }
        }else {
            return true;
        }

        return false;
    }
2.2二叉排序树的查找算法

思路:
如果当前节点小于target则向当前节点的右节点前进,如果右节点不存在说明没有这个target返回null;
如果当前节点大于target则向当前节点的左节点前进,如果左节点不存在说明没有这个target返回null;

public Object get(Object data){
        if(root == null){
            return null;
        }else {
            tree temp = root;
            while(temp!=null){
                Comparable comparable =(Comparable)temp.getData();
                if(comparable.compareTo(data)==1){
                    if(temp.getLeft()!=null)
                        temp = temp.getLeft();
                    else {
                        return null;
                    }
                }
                else if(comparable.compareTo(data)==-1){
                    if (temp.getRight() != null)
                        temp = temp.getRight();
                    else {
                        return null;
                    }
                }else{
                    if(data.equals(temp.getData()))   // data需要重写equals方法
                        return temp.getData();
                    else return null;
                }

            }
        }
        return null;
    }
2.3在二叉排序树删除结点的算法

删除节点有三种情况
(1)需要删除的节点左子树和右子树为空
此时可以直接将这个节点指空,最后返回空,使这个节点的父节点的子树设为空。
(2)如图所示,需要删除的节点左子树或者右子树为空,此时将现在的节点指向它的左子树(如果左子树为空则指向右子树)。
在这里插入图片描述
(3)如图所示,需要删除的节点的左右子树均存在,此时需要将左右子树中节点值跟它最接近的节点,变成此节点,这里取最接近它比他大的节点,也就是此节点右子树最深的左子树,也就是图中的10,然后调用删除节点的算法递归将子树15中的10删除
在这里插入图片描述

public void remove(Object data){
        this.root = deleteNode(this.root,data);
        if(size>0)
            size--;
    }
public tree deleteNode(tree root , Object data){
        if(root == null) return null;
        Comparable comparable = (Comparable) root.getData();
        if(comparable.compareTo(data)==1)
            root.setLeft(deleteNode(root.getLeft(),data));
        else if(comparable.compareTo(data)==-1)
            root.setRight(deleteNode(root.getRight(),data));
        else{
            if(root.getLeft()==null||root.getRight()==null){
                tree temp = root.getLeft()!=null ? root.getLeft():root.getRight();
                if(temp == null){
                    temp = root;
                    root = null;
                }else{
                    root = temp;
                    temp =null;
                }
            }else{
                tree temp = minValueNode(root.getRight());
                root.setData(temp.getData());
                root.setRight(deleteNode(root.getRight(),temp.getData()));
            }
        }
        if(root == null)
            return root;
        return root;
    }
    public tree minValueNode(tree Node){
        tree cur = Node;
        while(cur.getLeft()!=null){
            cur = cur.getLeft();
        }
        return cur;
    }

删除算法测试

在这里插入图片描述
在这里插入图片描述
完整代码
https://github.com/yhq915540781/javaPra/blob/master/src/Algorithm/dataStructure/searchBinaryTree.java

三、二叉排序树性能分析

由于所要查找的数据量不同,则其查找的性能也不同。且二叉排序树的平均查找长度与树的形态有关。最好情况是:二叉排序树和二叉判定树形态相同;最坏情况是:二叉排序为单支树,则其平均查找长度与顺序查找相同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值