数据结构之二叉查找树的实现

1. 代码实现

/**
 * @Classname BinaryTree
 * @author 10292356
 * @date 2021年8月30日 下午3:03:30
 * @Version 1.0
 */
public class BinaryTree<Key extends Comparable<Key>,Value> {
    private Node root;                  // 根节点
    private int num;                    // 树中元素的个数
    class Node {  // 节点内部类
        private Key key;    // 存储键
        private Value value;// 存储值
        private Node left;  // 左节点
        private Node right; // 右节点
        
        public Node(Key key,Value value,Node left,Node right) {
            this.key=key;
            this.value=value;
            this.left=left;
            this.right=right;
        }

        @Override
        public String toString() {
            return "Node [key=" + key + ", value=" + value + ", left=" + left + ", right=" + right + "]";
        }
        
    }
    // 获取树中元素的个数
    public int size() { 
        return num;
    }
    // 添加元素
    public void put(Key key,Value value) {
        root = put(root,key,value);
    }
    // 向指定的树节点中添加 k-v,并返回添加元素后的新树
    public Node put(Node x,Key key,Value value) {
        if(x == null) {
            num++;
            return new Node(key,value,null,null);
        }
        int cmp = key.compareTo(x.key);
        if(cmp>0) {
            x.right = put(x.right,key,value);
        }else if(cmp<0) {
            x.left = put(x.left,key,value);
        }else {
            x.value = value;
        }
        return x;
    }
    // 查询树中指定key对应的value值
    public Value get(Key key) {            
        return get(root,key);
    }
    // 从指定树x中,查找key对应的value值
    public Value get(Node x,Key key) {
        if(x == null) {
            return null;
        }
        int cmp = key.compareTo(x.key);
        if(cmp>0) {
            return get(x.right,key);
        }else if(cmp<0) {
            return get(x.left,key);
        }else {
            return x.value;
        }
    }
    // 删除树中key对应的value
    public void delete(Key key) {
        delete(root,key);
    }
    // 从指定树中,删除key对应的value,并返回删除节点后的新树
    public Node delete(Node x,Key key) {
        if(x == null) {
            return null;
        }
        int cmp = key.compareTo(x.key);
        if(cmp>0) {
            x.right = delete(x.right,key);
        }else if(cmp<0) {
            x.left = delete(x.left,key);
        }else {
            num--;
            if(x.right == null) {
                return x.left;
            }
            if(x.left == null) {
                return x.right;
            }
            Node minNode = x.right;
            while(minNode.left != null) {
                minNode = minNode.left; // 找到后继节点
            }
            Node n = x.right;
            while(n.left != null) {
                if(n.left.left == null) {
                    n.left = null;      // 删除后继节点
                }else {
                    n = n.left;
                }
            }
            minNode.left = x.left;      // 让被删除节点的左子树成为后继节点的左子树
            minNode.right = x.right;    // 让被删除节点的新右子树成为后继节点的右子树
            x = minNode;                // 让被删除节点的父节点指向后继节点
        }
        return x;
    }
    // 查找整个树中,最小的键
    public Key min() {
        return null;
    }
    // 查找整个树中,最大的键
    public Key max() {
        return null;
    }
    // 在指定树x中找出最小键所在的节点
    public Node min(Node x) {
        return null;
    }
    // 在指定树x中找出最大键所在的节点
    public Node max(Node x) {
        return null;
    }
}
 

2. 插入put方法的实现思路

        情况1:当前树中没有任何一个节点,则插入的节点即为根节点

        情况2:当前树不为空,则从根节点开始:

                1)如果新节点的key小于当前节点,则新插入节点则为当前节点的左节点

                2)如果新节点的key大于当前节点,则新插入节点则为当前节点的右节点

                3)如果新节点的key等于当前节点,则新插入节点的value替换当前节点的value值

3. 查询get方法的实现思路跟插入方法的一样

4. 删除delete方法的实现思路

        1)找到被删除节点

        2)找到被删除节点的后继节点

        3)删除右子树的后继节点,右子树更新为新右子树

        4)让左子树成为后继节点的左子树,让新右子树成为后继节点的右子树

        5)让被删除节点的父节点指向后继节点

5. 二叉树遍历

        1)前序遍历:先访问根节点,再访问左子树,最后访问右子树

        2)中序遍历:先访问左子树,再访问根节点,最后访问右子树

        3)后序遍历:先访问左子树,再访问右子树,最后访问根节点

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值