java实现二叉搜索树

1.前言

二叉搜索树是一种特殊的二叉树,它的每一个节点都满足以下条件:

  1. 左子树中所有节点的值均小于该节点的值。
  2. 右子树中所有节点的值均大于该节点的值。
  3. 每个子树也都是二叉搜索树。

通过这种特殊的结构,二叉搜索树能够实现快速的插入、查找和删除操作。在二叉搜索树中,插入一个新节点的时间复杂度为 O(log n),查找或删除一个节点的时间复杂度同样为 O(log n),其中 n 是树中节点的数量。

因为其高效的查找和排序性质,二叉搜索树被广泛应用于各种领域,例如数据库索引、哈希表等数据结构的实现、模拟字典等应用中。

2.原理分析

2.1添加节点

  1. 首先,需要确定要插入的节点在树中的位置。从根节点开始,与要插入的节点进行比较。

  2. 如果要插入的节点的值小于当前节点的值,那么就将其作为当前节点的左子节点。如果当前节点的左子节点为空,直接插入;如果不为空,将当前节点指向其左子节点,并继续执行第一步。

  3. 如果要插入的节点的值大于当前节点的值,那么就将其作为当前节点的右子节点。如果当前节点的右子节点为空,直接插入;如果不为空,将当前节点指向其右子节点,并继续执行第一步。

  4. 重复执行步骤 2 和步骤 3,直到找到合适的空位置插入节点。

2.2删除节点 

  1. 首先,我们需要找到要删除的节点。从根节点开始,比较要删除的值与当前节点的值,根据大小关系选择向左子树或右子树移动,直到找到与要删除的值相等的节点。

  2. 找到要删除的节点后,有以下几种情况:

    • 如果要删除的节点是叶节点(即没有左子树和右子树),直接将其从树中删除即可。

    • 如果要删除的节点只有左子树或只有右子树,我们需要用它的子节点来替代要删除的节点。

    • 如果要删除的节点既有左子树又有右子树,我们可以选择以下两种方式来替代要删除的节点:

      a. 在右子树中找到最小的节点,即右子树中的最左叶节点。将该节点的值复制到要删除的节点,并将该节点删除。这样可以保持二叉搜索树的性质。

      b. 在左子树中找到最大的节点,即左子树中的最右叶节点。将该节点的值复制到要删除的节点,并将该节点删除。同样,这样可以保持二叉搜索树的性质。

  3. 完成替代操作后,整个树的结构依然保持二叉搜索树的性质。

2.3查找节点 

  1. 从根节点开始,将要查找的值与当前节点的值进行比较。

  2. 如果要查找的值等于当前节点的值,那么说明找到了目标节点,返回当前节点。

  3. 如果要查找的值小于当前节点的值,那么说明目标节点位于当前节点的左子树中。则将当前节点指向其左子节点,并继续执行第一步。

  4. 如果要查找的值大于当前节点的值,那么说明目标节点位于当前节点的右子树中。则将当前节点指向其右子节点,并继续执行第一步。

  5. 重复执行步骤 2、3 和 4,直到找到目标节点或者遍历完整个树(表示目标节点不存在)。

3.代码实现 

3.1准备工作

 1.创建节点类
//创建节点类
    private static class TreeNode{

        T value;
        TreeNode left;
        TreeNode right;

        //叶节点专属构造方法
        public TreeNode(T value) {
            this.value = value;
            left = null;
            right = null;
        }

        //默认构造方法
        public TreeNode(T value, TreeNode left, TreeNode right) {
            this.value = value;
            this.left = left;
            this.right = right;
        }
    }
2.基础属性
public class TreeNodeTest>{

    private TreeNode root;//创建一个根节点




    public TreeNodeTest() {
        root = null;
    }

    //指定一个根节点创建树
    public TreeNodeTest(TreeNode root) {
        this.root = root;
    }

3.2插入节点 

  //插入节点
    public void insert(T value){
        root = insertRecursive(root, value);
    }


    //递归实现插入节点
    private TreeNode insertRecursive(TreeNode root, T value) {
        if (root == null){
            return new TreeNode<>(value);
        }
        if (value.compareTo(root.value) < 0){
            //小于此节点往此节点后面子节点继续找
            root.left = insertRecursive(root.left,value);
        }else if (value.compareTo(root.value) > 0){
            root.right = insertRecursive(root.right,value);
        }
        return root;
    }

3.3查找节点

 // 查找最小值节点
    private TreeNode findMin(TreeNode node) {
        if (node.left == null) {
            return node;
        }
        return findMin(node.left);
    }

    //查找节点
    public boolean contains(T value) {
        return containsRecursive(root, value);
    }


    //递归实现查找节点
    private boolean containsRecursive(TreeNode root, T value) {
        //递归的出口
        if (root == null){
            //意味着找到最后也没找到
            return false;
        }

        if (value.compareTo(root.value) == 0){
            return true;
        }

        if (value.compareTo(root.value) < 0){
            return containsRecursive(root.left,value);
        }else{
            return containsRecursive(root.right,value);
        }
    }

3.4删除节点

// 删除节点
    public void delete(T value) {
        root = deleteRecursive(root, value);
    }


    // 递归实现删除节点
    private TreeNode deleteRecursive(TreeNode root, T value) {
        if (root == null) {
            return null;
        }

        if (value.compareTo(root.value) < 0) {
            root.left = deleteRecursive(root.left, value);
        } else if (value.compareTo(root.value) > 0) {
            root.right = deleteRecursive(root.right, value);
        } else {
            // 找到要删除的节点
            if (root.left == null && root.right == null) {
                // 叶节点,直接删除
                return null;
            } else if (root.left == null) {
                // 只有右子树,用右子节点替代要删除的节点
                return root.right;
            } else if (root.right == null) {
                // 只有左子树,用左子节点替代要删除的节点
                return root.left;
            } else {
                // 左右子树都存在,找到右子树中最小的节点,替代要删除的节点
                TreeNode minNode = findMin(root.right);
                root.value = minNode.value;
                root.right = deleteRecursive(root.right, minNode.value);
            }
        }

        return root;
    }

3.5前中后序遍历

 // 前序遍历
    public void preOrderTraversal() {
        preOrderTraversalRecursive(root);
    }

    private void preOrderTraversalRecursive(TreeNode node) {
        if (node != null) {
            System.out.print(node.value + " ");
            preOrderTraversalRecursive(node.left);
            preOrderTraversalRecursive(node.right);
        }
    }

    // 中序遍历
    public void inOrderTraversal() {
        inOrderTraversalRecursive(root);
    }

    private void inOrderTraversalRecursive(TreeNode node) {
        if (node != null) {
            inOrderTraversalRecursive(node.left);
            System.out.print(node.value + " ");
            inOrderTraversalRecursive(node.right);
        }
    }

    // 后序遍历
    public void postOrderTraversal() {
        postOrderTraversalRecursive(root);
    }

    private void postOrderTraversalRecursive(TreeNode node) {
        if (node != null) {
            postOrderTraversalRecursive(node.left);
            postOrderTraversalRecursive(node.right);
            System.out.print(node.value + " ");
        }
    }

4.全部代码


/*
* 实现二叉树搜索树
*
* */


//因为是二叉搜索树所以要引入Comparable接口要不然引用类型无法比较
public class TreeNodeTest>{

    private TreeNode root;//创建一个根节点


    //创建节点类
    private static class TreeNode{

        T value;
        TreeNode left;
        TreeNode right;

        //叶节点专属构造方法
        public TreeNode(T value) {
            this.value = value;
            left = null;
            right = null;
        }

        //默认构造方法
        public TreeNode(T value, TreeNode left, TreeNode right) {
            this.value = value;
            this.left = left;
            this.right = right;
        }
    }

    public TreeNodeTest() {
        root = null;
    }

    //指定一个根节点创建树
    public TreeNodeTest(TreeNode root) {
        this.root = root;
    }

    //插入节点
    public void insert(T value){
        root = insertRecursive(root, value);
    }


    //递归实现插入节点
    private TreeNode insertRecursive(TreeNode root, T value) {
        if (root == null){
            return new TreeNode<>(value);
        }
        if (value.compareTo(root.value) < 0){
            //小于此节点往此节点后面子节点继续找
            root.left = insertRecursive(root.left,value);
        }else if (value.compareTo(root.value) > 0){
            root.right = insertRecursive(root.right,value);
        }
        return root;
    }
    // 删除节点
    public void delete(T value) {
        root = deleteRecursive(root, value);
    }


    // 递归实现删除节点
    private TreeNode deleteRecursive(TreeNode root, T value) {
        if (root == null) {
            return null;
        }

        if (value.compareTo(root.value) < 0) {
            root.left = deleteRecursive(root.left, value);
        } else if (value.compareTo(root.value) > 0) {
            root.right = deleteRecursive(root.right, value);
        } else {
            // 找到要删除的节点
            if (root.left == null && root.right == null) {
                // 叶节点,直接删除
                return null;
            } else if (root.left == null) {
                // 只有右子树,用右子节点替代要删除的节点
                return root.right;
            } else if (root.right == null) {
                // 只有左子树,用左子节点替代要删除的节点
                return root.left;
            } else {
                // 左右子树都存在,找到右子树中最小的节点,替代要删除的节点
                TreeNode minNode = findMin(root.right);
                root.value = minNode.value;
                root.right = deleteRecursive(root.right, minNode.value);
            }
        }

        return root;
    }
    // 查找最小值节点
    private TreeNode findMin(TreeNode node) {
        if (node.left == null) {
            return node;
        }
        return findMin(node.left);
    }

    //查找节点
    public boolean contains(T value) {
        return containsRecursive(root, value);
    }


    //递归实现查找节点
    private boolean containsRecursive(TreeNode root, T value) {
        //递归的出口
        if (root == null){
            //意味着找到最后也没找到
            return false;
        }

        if (value.compareTo(root.value) == 0){
            return true;
        }

        if (value.compareTo(root.value) < 0){
            return containsRecursive(root.left,value);
        }else{
            return containsRecursive(root.right,value);
        }
    }

    // 前序遍历
    public void preOrderTraversal() {
        preOrderTraversalRecursive(root);
    }

    private void preOrderTraversalRecursive(TreeNode node) {
        if (node != null) {
            System.out.print(node.value + " ");
            preOrderTraversalRecursive(node.left);
            preOrderTraversalRecursive(node.right);
        }
    }

    // 中序遍历
    public void inOrderTraversal() {
        inOrderTraversalRecursive(root);
    }

    private void inOrderTraversalRecursive(TreeNode node) {
        if (node != null) {
            inOrderTraversalRecursive(node.left);
            System.out.print(node.value + " ");
            inOrderTraversalRecursive(node.right);
        }
    }

    // 后序遍历
    public void postOrderTraversal() {
        postOrderTraversalRecursive(root);
    }

    private void postOrderTraversalRecursive(TreeNode node) {
        if (node != null) {
            postOrderTraversalRecursive(node.left);
            postOrderTraversalRecursive(node.right);
            System.out.print(node.value + " ");
        }
    }
    public static void main(String[] args) {
        TreeNodeTest tree = new TreeNodeTest<>();
        tree.insert(5);
        tree.insert(3);
        tree.insert(7);
        tree.insert(1);
        tree.insert(4);
        tree.insert(6);
        tree.insert(8);

        System.out.println("前序遍历结果:");
        tree.preOrderTraversal();

        System.out.println("\n中序遍历结果:");
        tree.inOrderTraversal();

        System.out.println("\n后序遍历结果:");
        tree.postOrderTraversal();

        System.out.println("\n是否包含值为 4 的节点:" + tree.contains(4));
    }
}




你可能感兴趣的:(算法,数据结构)