二叉查找树的java语言实现

二叉查找树的java语言实现

二叉查找树是什么?

​ 二叉查找树是一个树节点拥有不超过两个子节点的树,它的左子树节点的数据小于它本身的数据,它的右子树节点的数据大于它本身节点的数据,每一个的节点包含一个数据,我们在这里先假设这里面的每一个数据都是不相同的,为了方便后面的插入与删除操作。

二叉树的节点的实现

​ 因为是二叉查找树,所以节点是私有的,不能被公开。

​ 代码实现如下:

private static class BinaryNode<Item>{
        Item element;
        BinaryNode left;
        BinaryNode right;
        BinaryNode(Item element){
            this(element,null,null);
        }
        public BinaryNode(Item element, BinaryNode left, BinaryNode right) {
            this.element = element;
            this.left = left;
            this.right = right;
        }
    }

关于二叉查找树里面的可以进行的操作

​ 因为叫做二叉查找树,所以可以进行的操作主要以查找为主。

进行查找操作的方法介绍

  1. contain方法,看是否有这个数据包含在里面,如果有返回true,否则返回false;
  2. makeEmpty方法,是这颗树变为空树。
  3. isEmpty方法,看这棵树是否为空。
  4. findMin方法,找到这颗树的最小节点,可以通过根节点一直往左递归进行查找,直到递归到节点的左子树为空就找到了最小的节点。
  5. findMax方法,找到这棵树的最大节点,和找到最小节点的方法是一样的,只是这个是向右递归查找。
  6. insert方法,插入一个节点数据,注意当树里面有和节点数据相同的时,可以不做任何操作,也可以在附加域上做一个标记,例如有两个相同的数据,就实现2的附加域。
  7. remove方法,删除一个指定数据的节点,1:如果是一个树叶,就可以直接删除;2:如果这个节点有一个子树,就可以用这颗子树来代替删除的节点位置;3:如果有两颗子树,就用右子树里面的最小节点的数据来代替删除节点的数据,然后在通过递归删除右子节点的最小节点的数据,因为最小节点没有子树,所以很好删除,但是这个效率比较低,因为要进行两遍树的结点的查找。如图1:
  8. height方法,求树的高度的方法,注意当为一个树叶时,树的高度为0,所以树为空时,树的高度为-1。

进行树的遍历操作的方法介绍

  • 树的遍历是通过递归的方法来进行处理的,可以有三种常见的方法:
  • 前序遍历:先输出结点,在进行左右结点的输出。图片
  • 中序遍历:先输出左节点,在输出结点,在输出右结点。
  • 后序遍历:先输出左右结点,在进行结点的输出。

二叉查找树的代码实现

package com.ranyu.tree;

/**
 * @version 1.0
 * @Author ran_yu
 * @Date 2023/01/29 10:36
 **/
public class BinarySearchTree<Item extends Comparable<? super Item>> {
    private static class BinaryNode<Item> {
        Item element;
        BinaryNode<Item> left;
        BinaryNode<Item> right;

        BinaryNode(Item element) {
            this(element, null, null);
        }

        BinaryNode(Item element, BinaryNode<Item> left, BinaryNode<Item> right) {
            this.element = element;
            this.left = left;
            this.right = right;
        }
    }

    private BinaryNode<Item> root;//代表树的根结点

    public BinarySearchTree() {
        root = null;//此时先将根结点设置为空
    }

    /**
     * 判断树是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return root == null;
    }

    /**
     * 使树为空
     */
    public void makeEmpty() {
        root = null;
    }

    /**
     * 判断是否包含这个元素
     *
     * @param element
     * @return
     */
    public boolean contains(Item element) {
        return contains(element, root);
    }

    /**
     * 这是contains 方法的私有实现
     *
     * @param element
     * @param root
     * @return
     */
    private boolean contains(Item element, BinaryNode<Item> root) {
        if (root == null) {//首先先判断是否为空
            return false;
        }
        int result = element.compareTo(root.element);
        if (result < 0) {//如果小于,就往左递归
            return contains(element, root.left);
        } else if (result > 0) {//如果大于,就往右递归
            return contains(element, root.right);
        } else {
            return true;
        }
    }

    /**
     * 查找结点的最小值实现的是递归查找
     *
     * @return
     */
    public Item findMin() {
        if (isEmpty()) {
            return null;
        }
        return findMin(root).element;
    }

    /**
     * 查找findMin 的私有方法
     *
     * @param root
     * @return
     */
    private BinaryNode<Item> findMin(BinaryNode<Item> root) {
        if (root == null) {
            return null;
        } else if (root.left == null) {//如果结点的左结点为空,此时它就是最小的结点
            return root;
        }
        return findMin(root.left);//如果左结点不为空,在一直进行左字结点的遍历
    }

    /**
     * 对找最大元素实现的是循环查找
     *
     * @return
     */
    public Item findMax() {
        if (isEmpty()) {
            return null;
        }
        return findMax(root).element;
    }

    private BinaryNode<Item> findMax(BinaryNode<Item> root) {
        if (root == null) {
            return null;
        }
        while (root.right != null) {
            root = root.right;
        }
        return root;
    }

    /**
     * 进行元素的插入操作
     *
     * @param theElement
     */
    public void insert(Item theElement) {
        root = insert(theElement, root);
    }

    /**
     * 插入操作的私有方法
     *
     * @param theElement
     * @param root
     * @return
     */
    private BinaryNode<Item> insert(Item theElement, BinaryNode<Item> root) {
        if (root == null) {
            return new BinaryNode<Item>(theElement, null, null);
        }
        int result = theElement.compareTo(root.element);
        if (result < 0) {
            root.left=insert(theElement, root.left);
        } else if (result > 0) {
            root.right=insert(theElement, root.right);
        } else {
            //当树里面有这个元素时,此时不做任何操作
        }
        return root;
    }

    /**
     * 进行元素的删除方法
     *
     * @param theElement
     */
    public void remove(Item theElement) {
        root = remove(theElement, root);
    }

    /**
     * 进行元素删除的私有方法
     *
     * @param theElement
     * @param root
     * @return
     */
     private BinaryNode<Item> remove(Item theElement, BinaryNode<Item> root) {
        if (root == null) {
            return null;
        }
        int result = theElement.compareTo(root.element);
        if (result < 0) {
            root.left= remove(theElement, root.left);
        } else if (result > 0) {
            root.right= remove(theElement, root.right);
        } else if (root.left != null && root.right != null) {
            root.element = findMin(root.right).element;//得到右子树的最小元素
            root.right = remove(root.element, root.right);//此时就去删除右子树的最小结点,因为最小结点没有左子树和右子树,所以可以直接删除。
        } else {//这里是判断当只有一个子树,或者没有子树的情形。
            root = (root.left != null) ? root.left : root.right;
        }
        return root;
    }

    /**
     * 进行前序遍历
     */
    public void frontPrintTree() {
        if (isEmpty()) {
            System.out.println("empty tree");//表示为空树   
        } else {
            frontPrintTree(root);
        }
    }

    private void frontPrintTree(BinaryNode<Item> root) {
        if (root != null) {
            System.out.print(root.element + " ");
            frontPrintTree(root.left);
            frontPrintTree(root.right);
        }
    }

    /**
     * 中序遍历的实现
     */
    public void midPrintTree() {
        if (isEmpty()) {
            System.out.println("empty tree");
        } else {
            midPrintTree(root);
        }
    }

    private void midPrintTree(BinaryNode<Item> root) {
        if (root != null) {
            midPrintTree(root.left);
            System.out.print(root.element + " ");
            midPrintTree(root.right);
        }
    }

    /**
     * 后序遍历的实现
     */
    public void laterPrintTree() {
        if (isEmpty()) {
            System.out.println("empty tree");
        } else {
            midPrintTree(root);
        }
    }

    private void laterPrintTree(BinaryNode<Item> root) {
        if (root != null) {
            laterPrintTree(root.left);
            laterPrintTree(root.right);
            System.out.print(root.element + " ");
        }
    }

    /**
     * 求树的高度
     *
     * @return
     */
    public int height() {
        return height(root);
    }

    private int height(BinaryNode<Item> root) {
        if (root == null) {
            return -1;
        }
        return 1 + Math.max(height(root.left), height(root.right));
    }
    
}

进行测试

 public static void main(String[] args) {
        BinarySearchTree<Integer> tree = new BinarySearchTree<>();
        int[] arr={13,5,7,8,14,11,20,9,22,15};
        for (int i = 0; i < arr.length; i++) {
            tree.insert(arr[i]);
        }
        //测试树是否为空
        if(tree.isEmpty()){
            System.out.println("树为空");
        }else {
            System.out.println("树不为空");
        }

        int value=15;
        //测试包含方法是否可行
        if(tree.contains(value)){
            System.out.println("树中包含"+value);
        }else {
            System.out.println("树中不存在");
        }
        //测试找最小值
        Integer min = tree.findMin();
        System.out.println("最小值为: "+min);
        //测试找最大值
        Integer max = tree.findMax();
        System.out.println("最大值为: "+max);
        //进行遍历测试
        System.out.println("前序遍历");
        tree.frontPrintTree();
        System.out.println("中序遍历");
        tree.midPrintTree();
        System.out.println("后序遍历");
        tree.laterPrintTree();
        //测试树的高度
        int height = tree.height();
        System.out.println("高度为:"+height);
        //删除元素
        int deleteValue=15;
        System.out.println("删除前");
        tree.frontPrintTree();
        tree.remove(deleteValue);
        System.out.println("删除后");
        tree.frontPrintTree();
    }

输出结果为:

  • 树不为空
  • 树中包含15
  • 最小值为: 5
  • 最大值为: 22
  • 前序遍历
  • 13 5 7 8 11 9 14 20 15 22
  • 中序遍历
  • 5 7 8 9 11 13 14 15 20 22
  • 后序遍历
  • 5 7 8 9 11 13 14 15 20 22
  • 高度为:5
  • 删除前
  • 13 5 7 8 11 9 14 20 15 22
  • 删除后
  • 13 5 7 8 11 9 14 20 22
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值