Java实现二叉查找树及其相关操作

目录

二叉查找树

初始化

二叉查找树的查找

二叉查找树的插入 

二叉查找树的删除 

二叉查找树的中序遍历 

findMax and findMin 

二叉查找树完整代码 

测试用例 


完整代码已上传至gitee中:gitee代码仓库 

二叉查找树

二叉查找树,又称二叉排序树,亦称二叉搜索树,是数据结构中的一类。在一般情况下,查找效率比链表结构要高。

二叉查找树的定义

一棵空树或具有如下性质的树:

①若左子树不为空,则左子树上所有结点的值小于根结点的值;

②若右子树不为空,则右子树上所有结点的值大于根结点的值;

③左右子树也分别为二叉查找树

初始化

二叉查找树的初始化方式与二叉树一致.

public class TestBinarySearchTree {
    private static class TreeNode {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
    }
    //初始化根结点,默认初始化为null
    private TreeNode root;
}

二叉查找树的查找

①首先比较根结点,若根节点的关键字值等于查找的关键字值,则查找成功;

②若根节点的关键字值大于查找的关键字值,则查找左子树;

③若根节点的关键字值小于查找的关键字值,则查找右子树;

④若未查找到,则返回false,查找失败.

    /**
     * 二叉查找树的contains查找操作
     * @param val
     * @return
     */
    public boolean contains(int val) {
        if(root == null) {
            return false;
        }
        TreeNode cur = root;
        while(cur != null) {
            if(cur.val == val) {
                return true;
            }else if(cur.val > val) {
                cur = cur.left;
            }else {
                cur = cur.right;
            }
        }
        return false;
    }

二叉查找树的插入 

①若二叉树为空,则单独生成根结点;

②若二叉树不为空,则查找待插入的值应该放入的位置,之后进行插入即可,具体步骤如下:

        while(cur != null) {
            if(cur.val < val) {
                parent = cur;
                cur = cur.right;
            }else if(cur.val > val) {
                parent = cur;
                cur = cur.left;
            }else {
                return false;//不能插入相同的数字
            }
        }

之后比较parent.val与待插入值的大小来决定插入位置,具体代码如下: 

    /**
     * 二叉查找树的插入
     * @param val
     * @return
     */
    public boolean insert(int val) {
        if(root == null) {
            root = new TreeNode(val);
            return true;
        }
        TreeNode cur = root;
        TreeNode parent = null;
        while(cur != null) {
            if(cur.val < val) {
                parent = cur;
                cur = cur.right;
            }else if(cur.val > val) {
                parent = cur;
                cur = cur.left;
            }else {
                return false;//不能插入相同的数字
            }
        }
        if(parent.val < val) {
            parent.right = new TreeNode(val);
        }else {
            parent.left = new TreeNode(val);
        }
        return true;
    }

二叉查找树的删除 

 二叉查找树的删除操作,首先找到待删除的结点和其parent结点,之后进行删除操作:

1、当cur.left == null时:

①若cur是root,则令root = cur.right;

②若cur是parent.left,则parent.left = cur.right; 

③若cur是parent.right,则parent.right = cur.right;

2、当cur.right == null时:

①若cur是root,则令root = cur.left;

②若cur是parent.left,则parent.left = cur.left;

③若cur是parent.right,则parent.right = cur.left;

3、如果不满足上列两个判断条件,则另外进行判断,具体代码如下: 

    /**
     * 二叉查找树的删除
     * @param val
     * @return
     */
    public boolean remove(int val) {
        if(root == null) {
            return false;
        }
        TreeNode cur = root;
        TreeNode parent = null;
        while(cur != null) {
            if(cur.val < val) {
                parent = cur;
                cur = cur.right;
            }else if(cur.val > val) {
                parent = cur;
                cur = cur.left;
            }else {
                removeNode(parent,cur);
                return true;
            }
        }
        return false;
    }

    public void removeNode(TreeNode parent, TreeNode cur) {
        if(cur.left == null) {
            if(cur == root) {
                root = cur.right;
            }else if(parent.right == cur) {
                parent.right = cur.right;
            }else {
                parent.left = cur.right;
            }
        }else if(cur.right == null) {
            if(cur == root) {
                cur = cur.left;
            }else if(parent.left == cur) {
                parent.left = cur.left;
            }else {
                parent.right = cur.left;
            }
        }else {
            TreeNode target = cur.right;
            TreeNode targetParent = cur;
            while(target != null) {
                targetParent = target;
                target = target.left;
            }
            cur.val = target.val;
            if(target == targetParent.left) {
                targetParent.left = target.right;
            }else {
                targetParent.right = target.right;
            }
        }
    }

二叉查找树的中序遍历 

即将从小到大排序后的数据输出 

    /**
     * 二叉查找树的中序遍历
     * @param root
     */
    public void inorder(TreeNode root) {
        if(root == null) {
            return ;
        }
        inorder(root.left);
        System.out.print(root.val + " ");
        inorder(root.right);
    }

findMax and findMin 

根据分析可知,二叉查找树最左边一个结点为其最小值,最右边的一个结点为其最大值,则根据该性质,可以写出如下代码: 

    /**
     * 输出二叉查找树中的最大值
     * @param root
     */
    public void findMax(TreeNode root) {
        if(root == null) {
            System.out.println("二叉查找树为空");
            return ;
        }
        while(root.right != null) {
            root = root.right;
        }
        System.out.println("最大值为:" + root.val);
    }

    /**
     * 输出二叉查找树中的最小值
     * @param root
     */
    public void findMin(TreeNode root) {
        if(root == null) {
            System.out.println("二叉查找树为空");
            return ;
        }
        while(root.left != null) {
            root = root.left;
        }
        System.out.println("最小值为:" + root.val);
    }

二叉查找树完整代码 

public class TestBinarySearchTree {
    private static class TreeNode {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
    }

    private TreeNode root;

    /**
     * 二叉查找树的contains操作
     * @param val
     * @return
     */
    public boolean contains(int val) {
        if(root == null) {
            return false;
        }
        TreeNode cur = root;
        while(cur != null) {
            if(cur.val == val) {
                return true;
            }else if(cur.val > val) {
                cur = cur.left;
            }else {
                cur = cur.right;
            }
        }
        return false;
    }

    /**
     * 二叉查找树的插入
     * @param val
     * @return
     */
    public boolean insert(int val) {
        if(root == null) {
            root = new TreeNode(val);
            return true;
        }
        TreeNode cur = root;
        TreeNode parent = null;
        while(cur != null) {
            if(cur.val < val) {
                parent = cur;
                cur = cur.right;
            }else if(cur.val > val) {
                parent = cur;
                cur = cur.left;
            }else {
                return false;//不能插入相同的数字
            }
        }
        if(parent.val < val) {
            parent.right = new TreeNode(val);
        }else {
            parent.left = new TreeNode(val);
        }
        return true;
    }

    /**
     * 二叉查找树的删除
     * @param val
     * @return
     */
    public boolean remove(int val) {
        if(root == null) {
            return false;
        }
        TreeNode cur = root;
        TreeNode parent = null;
        while(cur != null) {
            if(cur.val < val) {
                parent = cur;
                cur = cur.right;
            }else if(cur.val > val) {
                parent = cur;
                cur = cur.left;
            }else {
                removeNode(parent,cur);
                return true;
            }
        }
        return false;
    }

    public void removeNode(TreeNode parent, TreeNode cur) {
        if(cur.left == null) {
            if(cur == root) {
                root = cur.right;
            }else if(parent.right == cur) {
                parent.right = cur.right;
            }else {
                parent.left = cur.right;
            }
        }else if(cur.right == null) {
            if(cur == root) {
                cur = cur.left;
            }else if(parent.left == cur) {
                parent.left = cur.left;
            }else {
                parent.right = cur.left;
            }
        }else {
            TreeNode target = cur.right;
            TreeNode targetParent = cur;
            while(target != null) {
                targetParent = target;
                target = target.left;
            }
            cur.val = target.val;
            if(target == targetParent.left) {
                targetParent.left = target.right;
            }else {
                targetParent.right = target.right;
            }
        }
    }

    /**
     * 二叉查找树的中序遍历
     * @param root
     */
    public void inorder(TreeNode root) {
        if(root == null) {
            return ;
        }
        inorder(root.left);
        System.out.print(root.val + " ");
        inorder(root.right);
    }

    /**
     * 输出二叉查找树中的最大值
     * @param root
     */
    public void findMax(TreeNode root) {
        if(root == null) {
            System.out.println("二叉查找树为空");
            return ;
        }
        while(root.right != null) {
            root = root.right;
        }
        System.out.println("最大值为:" + root.val);
    }

    /**
     * 输出二叉查找树中的最小值
     * @param root
     */
    public void findMin(TreeNode root) {
        if(root == null) {
            System.out.println("二叉查找树为空");
            return ;
        }
        while(root.left != null) {
            root = root.left;
        }
        System.out.println("最小值为:" + root.val);
    }
}

测试用例 

测试代码以及测试结果如下所示

public class TestDemo {
    public static void main(String[] args) {
        TestBinarySearchTree tree = new TestBinarySearchTree();
        //创建二叉查找树
        tree.insert(5);
        tree.insert(8);
        tree.insert(1);
        tree.insert(10);
        tree.insert(16);
        tree.insert(3);
        tree.insert(4);
        System.out.println("二叉查找树的中序遍历");
        tree.inorder(tree.root);
        System.out.println("\n" + "===================");
        System.out.println("二叉查找树的查找,查找16");
        System.out.println(tree.contains(16));
        System.out.println("\n" + "===================");
        System.out.println("二叉查找树的插入,插入21");
        tree.insert(21);
        tree.inorder(tree.root);
        System.out.println("\n" + "===================");
        System.out.println("二叉查找树的删除,删除1");
        tree.remove(1);
        tree.inorder(tree.root);
        System.out.println("\n" + "===================");
        System.out.println("输出二叉查找树的最大值和最小值");
        tree.findMax(tree.root);
        tree.findMin(tree.root);
    }
}

测试结果 

二叉查找树的中序遍历
1 3 4 5 8 10 16 
===================
二叉查找树的查找,查找16
true

===================
二叉查找树的插入,插入21
1 3 4 5 8 10 16 21 
===================
二叉查找树的删除,删除1
3 4 5 8 10 16 21 
===================
输出二叉查找树的最大值和最小值
最大值为:21
最小值为:3

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Li_yizYa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值