二叉搜索树的基本操作

查找元素

public class Node{
    int key;
    Node left;
    Node right;

    public Node(int key) {
        this.key = key;
    }
}
private Node root = null;
public Node find(int key){
    //查找key是否在树中存在,如果存在就返回对应Node
    Node cur = root;
    while(cur != null){
        if(key < cur.key){
            //去左子树中找
            cur = cur.left;
        }else if(key > cur.key){
            //去右子树中找
            cur = cur.right;
        }else{
            //相等就是找到了
            return cur;
        }
    }
    //循环结束也没找到
    return null;
}

插入元素

二叉搜索树不允许存在相同元素
如果发现新插入的key重复,就会插入失败
插入成功就返回true

public boolean insert(int key){
    if(root == null){
        //当前如果为空树,直接让root指向key对应的新节点即可
        root = new Node(key);
        return true;
    }
    Node cur = root;
    Node parent = null;
    //始终指向cur的父节点,和链表插入类似,插入过程需要记录前一个节点
    while(cur != null){
        if(key < cur.key){
            parent = cur;
            cur = cur.left;
        }else if(key > cur.key){
            parent = cur;
            cur = cur.right;
        }else{
            //如果当前树存在的是key,发现相同key就插入失败了
            //如果当前树存的是键值对,发现相同key修改值即可
            return false;
        }
    }
    //循环结束,cur就指向null了,当前元素就就要插入parent的子树位置
    //具体是左子树还是右子树,需要key和parent再进行比较
    if(key < parent.key){
        //插入到parent的左侧
        parent.left = new Node(key);
    }else{
        parent.right = new Node(key);
    }
    return true;
}

删除元素

删除成功返回true,删除失败返回false
key在树中存在,删除成功
key在树中不存在,删除失败

public boolean remove(int key) {
    //先找到待删除节点的位置,再进行具体的删除
    Node cur = root;
    Node parent = null;
    while (cur != null) {
        if (key < cur.key) {
            parent = cur;
            cur = cur.left;
        } else if (key > cur.key) {
            parent = cur;
            cur = cur.right;
        } else {
            //要删除的元素就是cur指向的节点
            removeNode(parent, cur);
        }
    }
    //循环结束,要删除的元素不存在
    return false;
}
private void removeNode(Node parent, Node cur) {
    if(cur.left == null){
        //1.要删除的元素没有左子树
        if(cur == root){
            //1.1要删除的元素是根节点
            root = cur.right;
        }else if(cur == parent.left){
            //1.2要删除的元素是父节点的左子树
            parent.left = cur.right;
        }else{
            //1.3要删除的元素是父节点的右子树
            parent.right = cur.right;
        }
    }else if(cur.right == null){
        //2.要删除的元素没有右子树
        if(cur == root){
            //2.1要删除的元素是根节点
            root = cur.left;
        }else if(cur == parent.left){
            //2.2要删除的元素是父节点的左子树
            parent.left = cur.left;
        }else{
            //2.3要删除的元素是父节点的右子树
            parent.right = cur.left;
        }
    }else{
        //3.要删除的元素有两个子树--无法直接删除,需要换个思路进行删除
        //找到左子树的最大值(或者右子树的最小值)--替罪羊,把要删除元素用替罪羊替换,最后删除替罪羊
        //要先找到右子树最小元素(替罪羊)
        Node scapeGoat = cur.right;//替罪羊节点
        Node goatParent = cur;//替罪羊节点的父节点
        while(cur != null){
            goatParent = scapeGoat;
            scapeGoat = cur.left;
        }
        //循环结束,scapeGoat就指向了替罪羊节点
        //把替罪羊节点赋给待删除节点
        cur.key = scapeGoat.key;
        //删除替罪羊节点(替罪羊节点一定没有左子树)
        //此处还需要判断替罪羊节点是父节点的左子树还是右子树
        if(scapeGoat == goatParent.left){
            goatParent.left = scapeGoat.right;
        }else{
            goatParent.right = scapeGoat.right;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值