二叉搜索树的模拟实现——Java数据结构

简介: 二叉搜索树的模拟实现——Java数据结构

概念:

 

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

📝若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

📝它的左右子树也分别为二叉搜索树

090fb26ecb0c4f39964194f3c7f3eb56.png

模拟实现的代码:

public class BinarySearchTree {
   static class TreeNode {
        public int key;
        public TreeNode left;
        public TreeNode right;
        TreeNode(int key) {
            this.key = key;
        }
    }
    public TreeNode root;
    public void insert(int key) {
        if (root == null) {
            root = new TreeNode(key);
        }
        else {
            TreeNode parent = null;
            TreeNode cur = root;
            TreeNode node = new TreeNode(key);
            while (cur != null) {
                // 为什么不在while循环了出现node,因为对于二叉搜索树来说,我们都是在叶子结点的位置插入元素,你想想后面的元素是要先遍历到叶子结点,然后在插入
                // 因为每次插入新结点都要从上到下遍历一遍二叉树,不能在中间就把结点盲目的插入了,这样不符合二叉搜索树的要求
                if (cur.key > key) {
                    parent = cur;
                    cur = cur.left;
                }
                else if (cur.key < key) {
                    parent = cur;
                    cur = cur.right;
                }
                else {
                    return; // 插入元素的值不能相同,二叉搜索树的要求
                }
            }
            // 当程序走到这,cur == null
            if (parent.key > key) {
                parent.left = node;
            }
            else {
                parent.right = node;
            }
        }
    }
    // 如果是二叉搜索树,中序遍历的值就是有序的
    public void inorder(TreeNode root) {
        if (root == null) {
            return;
        }
        inorder(root.left);
        System.out.print(root.key + " ");
        inorder(root.right);
    }
    // 二叉搜索树的查找
    public TreeNode search(int key) {
        TreeNode cur = root;
        while (cur != null) {
            if (cur.key < key) {
                cur = cur.right;
            }
            else if (cur.key > key) {
                cur = cur.left;
            }
            else {
                return cur;
            }
        }
        return null;
    }
    // 二叉搜索树的删除操作
    public boolean remove(int key) {
        TreeNode cur = root;
        TreeNode parent = null;
        while (cur != null) {
            if (cur.key > key) {
                parent = cur;
                cur = cur.left;
            }
            else if (cur.key < key) {
                parent = cur;
                cur = cur.right;
            }
            else {
                removeKey(parent, cur);
                return true;
            }
        }
        return false;
    }
    // 删除结点的具体操作
    public void removeKey(TreeNode parent, TreeNode cur) {
        if (cur.right == null) {
            if (cur == root) {
                root = cur.left;
            }
            if (parent.key < cur.key) {
                parent.right = cur.left;
            }
            else {
                parent.left = cur.left;
            }
        }
        else if (cur.left == null) {
            if (cur == root) {
                root = cur.right;
            }
            if (parent.key < cur.key) {
                parent.right = cur.right;
            }
            else {
                parent.left = cur.right;
            }
        }
        else {  // 当要删除结点的左右子结点都不为空的时候
            TreeNode targetParent = cur;
            TreeNode target = cur.right; // 我们所寻找的target就是要删除结点cur的右子树的最小值
            // 寻找要删除结点cur的右子树的最小值,将该最小值所对应的结点的值覆盖掉要删除的结点的值,
            // 此时要删除的结点就相当于是删除了,并且此时满足二叉搜索树的性质(不要忘了把最小值的原位置结点给删除)
            // 对于最小值结点来说,他的左子结点一定为空(删除方法和我们上面的方法是一样的)
            while (target.left != null) {
                targetParent = target;
                target = target.left;
            }
            // 此时的target要删除结点cur的右子树的最小值所对应的结点
            cur.key = target.key;  // 用target的值覆盖掉要删除结点cur的值
            // 覆盖掉后把target结点删除, 对于最小值结点来说,他的左子结点一定为空(删除方法和我们上面的方法是一样的)
            if (targetParent.key > target.key) {
                targetParent.left = target.right;
            }
            else {
                targetParent.right = target.right;
            }
        }
    }
}

测试代码

public class Test {
    public static void main(String[] args) {
        BinarySearchTree binarySearchTree = new BinarySearchTree();
        int[] array = {12, 32, 2, 43, 21, 14};
        for (int i = 0; i < array.length; i++) {
            binarySearchTree.insert(array[i]);
        }
        binarySearchTree.inorder(binarySearchTree.root);
        System.out.println();
        // 如果TreeNode不是静态内部类需要这样实例化——BinarySearchTree.TreeNode treeNode = binarySearchTree.new TreeNode(12);
        // 静态内部类直接— BinarySearchTree.TreeNode treeNode = new BinarySearchTree.TreeNode(12);
        BinarySearchTree.TreeNode ret = binarySearchTree.search(423);
        try {
            System.out.println(ret.key);
        } catch (NullPointerException e) {
            System.out.println("该二叉搜索树中没有你要查找的结点");
            //e.printStackTrace();
        }
        System.out.println("==========================");
        binarySearchTree.remove(32);
        binarySearchTree.inorder(binarySearchTree.root);
    }
}

c13a32e5d25645d08b4e0b8865c60b7b.png

相关文章
|
1月前
|
算法 搜索推荐 Java
数据结构与算法(Java篇)笔记--希尔排序
数据结构与算法(Java篇)笔记--希尔排序
|
1月前
|
算法
【数据结构】二叉搜索树
【数据结构】二叉搜索树
21 2
|
29天前
|
存储 算法 Java
Java数据结构与算法-java数据结构与算法(二)
Java数据结构与算法-java数据结构与算法
88 1
|
1天前
|
存储 安全 Java
Java并发编程中的高效数据结构:ConcurrentHashMap解析
【4月更文挑战第25天】在多线程环境下,高效的数据访问和管理是至关重要的。Java提供了多种并发集合来处理这种情境,其中ConcurrentHashMap是最广泛使用的一个。本文将深入分析ConcurrentHashMap的内部工作原理、性能特点以及它如何在保证线程安全的同时提供高并发性,最后将展示其在实际开发中的应用示例。
|
7天前
|
存储 供应链 Java
《Java 简易速速上手小册》第3章:Java 数据结构(2024 最新版)
《Java 简易速速上手小册》第3章:Java 数据结构(2024 最新版)
6 1
|
14天前
|
Java API
编码的奇迹:Java 21引入有序集合,数据结构再进化
编码的奇迹:Java 21引入有序集合,数据结构再进化
16 0
|
29天前
|
XML 存储 算法
Java数据结构与算法-java数据结构与算法(五)
Java数据结构与算法-java数据结构与算法
48 0
|
1月前
|
缓存 安全 Java
Java并发编程中的高效数据结构 - ConcurrentHashMap
本文将深入探讨Java并发编程中的一种高效数据结构 - ConcurrentHashMap。我们将详细介绍ConcurrentHashMap的基本原理,包括其设计思路、实现方式以及如何在多线程环境下提供高效的并发访问。同时,我们还将通过实例代码演示如何使用ConcurrentHashMap来优化并发程序的性能。
|
1月前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
94 3
|
1月前
|
算法 搜索推荐 Java
数据结构与算法(Java篇)笔记--快速排序
数据结构与算法(Java篇)笔记--快速排序