Python 每日一记243>>>Java二叉树添加、查找、删除方法的实现

关于这一部分的知识没有想的太明白,因此肯定表达不是很清楚,因此直接上代码了,后续再进行消化。

package mypackage;

import com.sun.security.auth.module.UnixLoginModule;

import javax.print.DocFlavor;
import java.util.IllegalFormatCodePointException;

//二叉树类
class Btree<key extends Comparable, value> {

    public Node root;
    public int N;

//    节点类,包括键值对,左子节点和右子节点
    public class Node {
        public key key;
        public value value;
        public Node left;
        public Node right;

        public Node(key key, value value, Node left, Node right) {
            this.key = key;
            this.value = value;
            this.left = left;
            this.right = right;
        }
    }

    //   获取元素个数
    public int size() {
        return N;
    }

    //   向树中添加元素,这个是对外调用的方法,从root开始递归,添加元素
//    核心是下面的put(Node node, key key, value value)方法
    public void put(key key, value value) {
        root = put(root, key, value);
    }


    //   向指定树中添加元素
    public Node put(Node node, key key, value value) {
//        如果子树node为空,直接返回新节点
//        其实这个是递归结束的条件之一
        if (node == null) {
            N++;
            return new Node(key, value, null, null);
        }

//        判断如果key大于node.key,向右子树递归
        int compare1 = key.compareTo(node.key);
        if (compare1 > 0) {
//            注意为什么不put(node.right, key, value),还要加上node.right = ?
//            这样才能实现节点节点之间的连接,因为put(node.right, key, value);返回的是node.right
            node.right = put(node.right, key, value);
            //        判断如果key小于node.key,向左子树递归
        } else if (compare1 < 0) {
            node.left = put(node.left, key, value);
            //        判断如果key==node.key,替换这个值
        } else {
            node.value = value;
        }
//        返回这个节点
        return node;
    }

//    查询某key的值这个是对外调用的方法,从root开始递归,查询元素
//   核心是下面的get(Node node, key key)方法
    public value get(key key){
        return get(root,key);
    }

    //    查询指定子树某key的值
    public value get(Node node, key key){
//        如果为空,无法找到,返回null
        if (node==null){
            return null;
        }
        int compare1 = key.compareTo(node.key);
//        判断如果key大于node.key,向右子树递归
        if (compare1 > 0) {
            return get(node.right,key);
            //        判断如果key小于node.key,向左子树递归
        } else if (compare1 < 0) {
            return get(node.left,key);
            //        判断如果key==node.key,找到这个值
        } else {
            return node.value;
        }
    }

//    删除操作,比较麻烦的操作,
//    主要是因为删除一个节点后,原本这个节点有左右子树的话,要找一个节点去填充这个节点,
//    找哪个节点去填充呢,找右子数种最小的节点,这个节点能满足大于左子树种中的所有节点,小于右子树的所有节点
//    如果这个节点没有右子树,只有左子树,让上一个节点连接这个节点的下一个节点
//    如果没有左、右子树,直接删除就行了
    public void delete(key key){
        root=delete(root,key);
    }

//    删除指定数种的key对应的value,并返回删除后的新树
    public Node delete(Node node,key key){
//        如果节点不存在就返回null
        if (node==null){
            return null;
        }

        int compare1 = key.compareTo(node.key);
//        判断如果key大于node.key,向右子树递归
        if (compare1 > 0) {
//            递归,结果返回删除后的新树,让node.right指向返回的新树
            node.right = delete(node.right, key);
            //        判断如果key小于node.key,向左子树递归
        } else if (compare1 < 0) {
//            递归,结果返回删除后的新树,让node.left指向返回的新树
            node.left = delete(node.left, key);
//            判断如果key==node.key,找到了这个要删除的值,之后要找到一个值来填充这个位置
        } else {
            N--;
//            如果没有右子树,返回的新树为当前结点的左子树即可
            if (node.right==null){
                return node.left;
            }
//            如果没有左子树,返回的新树为当前结点的右子树即可
            if (node.left==null){
                return node.right;
            }
//            如果有左子树和右子树,去找右子树中的最小的值
            Node minNode=node.right;
//            一直找左子树就是最小的值,如果没有左子树,那么当前就是最小的值
            while (minNode.left!=null){
                minNode=minNode.left;
            }
//            上面找到了最小节点,现在要删除这个最小节点,然后放到待删除的节点处覆盖
//            怎么删除呢,就是要找到这个节点的上一个节点,让他指向null
//            因此关键就是要找到最小节点的上一个节点
            Node cur=node.right;
            Node pre=node;
//            如果待删除节点的右子树有左节点,那么就去找这个最小的左节点
//            然后让最小节点的上一个节点指向null
            if (cur.left!=null){
                while (cur.left!=null){
                    pre=cur;
                    cur=cur.left;
                }
                pre.left=null;
//                如果待删除节点的右子树没有左节点,这个时候又要分两种情况
//                一种情况是没有左节点且没有右节点,这时让node.right指向null即可
//                另外一种情况是没有左节点但是有右节点,因此要让node.right指向node.right.right
            }else {
                if (cur.right==null){
                    pre.right=null;
                }else {
                    pre.right=cur.right;
                }
            }
//            删除最小元素后,让最小元素左子树为待删除元素的左子树,让最小元素右子树为待删除元素的右子树
            minNode.left=node.left;
            minNode.right=node.right;
//            这个是让node的上一个节点指向这个最小的节点,此时这个最小的节点已经替换了待删除的元素的位置
            node= minNode;
        }
//        这个返回值至关重要,作为这个方法的返回值,
//        用作上一级的node.right = delete(node.right, key)或者node.left = delete(node.left, key)的返回值
        return node;
    }

//    查找树中最小的key,调用重载方法
    public key getmin(){
        return getmin(root).key;
    }
    //    查找指定树中最小的key的节点
//    递归去找右子树
    public Node getmin(Node node){
        if (node.left!=null){
            return getmin(node.left);
        }else {
            return node;
        }
    }

    //    查找树中最大的key,调用重载方法
    public key getmax(){
        return getmax(root).key;
    }
    //    查找指定树中最大的key的节点
    //    递归去找右子树
    public Node getmax(Node node){
        if (node.right!=null){
            return getmax(node.right);
        }else {
            return node;
        }
    }
}

//测试
public class MyJava {

    public static void main(String[] args) {
        Btree<Integer,String>btree=new Btree();
//        插入元素
        btree.put(6,"刘备");
        btree.put(4,"关羽");
        btree.put(9,"张飞");
        btree.put(1,"曹操");
        btree.put(5,"吕布");
        btree.put(7,"黄忠");
        btree.put(10,"赵云");
        System.out.println("插入完毕后元素的个数为:"+btree.size());

//        查询元素
        System.out.println("查询key=4元素:"+btree.get(4));

//        找最小的key
        System.out.println("最小的key:"+btree.getmin());
//        找最大的key
        System.out.println("最大的key:"+btree.getmax());

//        删除元素
        btree.delete(4);
        System.out.println("删除后元素个数:"+btree.size());
        System.out.println("删除后查询4元素:"+btree.get(4));
    }
}

结果:

在这里插入图片描述

发布了235 篇原创文章 · 获赞 24 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_44663675/article/details/105606076