二叉查找树

一、二叉树定义:

二叉树就是度不超过2的树(即每个节点最多有两个子结点)

满二叉树定义:

一个二叉树,每一层的结点树都达到了最大值,就称为满二叉树

二、二叉查找树API设计:

  • 二叉查找树每个结点都是储存一个key和一个value。
  • 本文用链表实现二叉查找树

三、二叉查找树的实现

接口Comparable<T>的使用:

  • 注意程序这里要写上Key继承了Comparable接口,然后后面才可以调用compareTo方法

 

四、二叉查找树的增(put)删(delete)查(get)

package day02;

public class BinaryTree<Key extends Comparable<Key>,Value>{

    private Node root;//根结点
    private int N;//结点个数

    //内部类
    class Node{

        public Node left; //左子结点
        public Node right; //右子结点
        public Key key;
        public Value value;

        //构造器
        public Node(Node left,Node right,Key key,Value value){
            this.left = left;
            this.right = right;
            this.key = key;
            this.value = value;
        }
    }


    public int size(){
        return N;
    }


    //向整个树中添加结点 key-value
    // 注意:此方法会把新插入的值作为root结点
    public void put(Key key, Value value){
        root = put(root,key,value);
    }


    //在指定结点x下的子树中插入新的结点 key-value
    public Node put(Node x, Key key, Value value){

        //如果x结点为空
        if(x==null){
            N++;
            return new Node(null,null,key,value);
        }

        //如果x结点不为空,则比较x.key和key的大小
        int var = key.compareTo(x.key);
        if(var>0){
            //即key大于x结点的键
            x.right = put(x.right,key,value);//用了递归的思想
        }else if(var<0){
            x.left = put(x.left,key,value);
        }else{
            x.value = value;
            x.key = key;
        }

        return x;//x即为新被插入的结点
    }


    //在整个树中查询指定key对应的value
    public Value get(Key key){
        return get(root,key);
    }


    //在指定结点下查找指定key对应的value
    public Value get(Node x,Key key){

        //1.当x=null
        if(x==null){
            return null;
        }
        //2.当x!=null
        int var = key.compareTo(x.key);
        if(var>0){
            return get(x.right,key);//用了递归的思想
        }else if(var<0){
            return get(x.left,key);
        }else{
            //找到了目标结点
            return x.value;
        }
    }


    //删除树中对应的key结点
    public void delete(Key key){
        delete(root,key);
    }


    //删除指定结点x下的对应key结点,并返回
    public Node delete(Node x,Key key){
        //1.x为null
        if(x==null){
            //说明没找到对应结点
            return null;
        }

        //2.x不为null
        int var = key.compareTo(x.key);
        if(var>0){
            x.right = delete(x.right,key);
        }else if(var<0){
            x.left = delete(x.left,key);
        }else{
            //找到了待删除结点x
            N--;

            //1.只有左子树
            if(x.right==null){
                return x.left;
            }

            //2.只有右子树
            if(x.left==null){
                return x.right;
            }

            //3.x左右子树都有,找到x右子树中的key最小值结点minNode来替换待删除结点,然后删除原来位置的minNode连接
            Node minNode = x.right;
            while(minNode.left!=null){
                minNode = minNode.left;
            }//此时minNode为x右子树中的key最小值结点

            //断开minNode的连接
            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的左子树指向x的左子树
            minNode.right = x.right;//让minNode的右子树指向x的右子树

            //让x结点的父结点指向minNode
            x = minNode;//因为程序前面有x.right = delete(x.right,key);,递归时就让x结点的父结点指向minNode
        }

        return x;
    }


    //查找整个树的最小键
    public Key minKey(){
        return minKey(root).key;
    }


    //指定树x中找出最小键所在结点
    //注意x结点右侧子树的所有结点都比x的key大
    public Node minKey(Node x){
        //此方法采用循环,没有有迭代。效果一样
        while (x.left!=null){
            x = x.left;
        }
        return x;
    }


    //查找整个树中最大的键
    public Key maxKey(){
        return maxKey(root).key;
    }


    //查找指定树x中最大键所在结点
    //递归的条件:1.可以分解成很多子问题2.每一次递归调用,子问题使情况朝着基准情况推进3.基准情况即不用递归便可解出
    public Node maxKey(Node x){
        if(x.right!=null){
            return maxKey(x.right);
        }else {
            return x;
        }
    }




}

测试程序:

五、二叉查找树的遍历

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值