java实现二叉查找树

1.二叉树概念

概念:二叉树是一棵树,其中每个节点不能多于两个儿子

2.图解分析

2.1 模拟器地址

二叉树:https://www.cs.usfca.edu/~galles/visualization/BST.html
所有数据结构:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

2.2添加

如果依次添加6,2,1,4,3,5,8节点,结果如下图
第一个添加的节点为根,后面添加的节点大于根往右,小于根往左
在这里插入图片描述

2.3 删除

2.3.1 删除节点1

在这里插入图片描述

  • 第一步:1小于6 向左寻找到2
  • 第二步:1小于2 向左寻找1
  • 第三步:设置2的左边节点为节点1的左边节点(如果有左边节点的话) 图中为null
  • 第三步核心代码: root = (root.left != null) ? root.left : root.right;

2.3.2 删除节点2

在这里插入图片描述

  • 第一步:2小于6 向左寻找到3
  • 第二步:2小于3 向左寻找到2
  • 第三步:设置3的左边节点为2的左边节点
  • 第三步核心代码:root = (root.left != null) ? root.left : root.right;
  • ps:第一种情况何和第二种情况本质上是一样的,只是第一种情况恰好被删除节点没有儿子

2.3.3 删除节点4

当需要删除的节点有左右两个儿子的时候

2.3.3.1第一种实现方式

在这里插入图片描述

  • 第一步:4小于6 向左寻找到2
  • 第二步:4大于2 向右寻找4为删除节点
  • 第三步:找到4节点右树中最小的节点5作为替换节点
  • 第四步:设置2的右节点为5(只替换节点本身,原左边3自动转化为节点5的左边节点)
  • 第五步:删除原来5节点中的5节点 剩余节点为5的右节点
  • 核心代码:
    //找到右树中的最小节点5代替4
    root.element = findMin(root.right).element; //找到5
    //删除原来5节点中的5节点 剩余节点为5的右节点
    root.right = remove(root.element, root.right);
    //root.left 还是原来的3
2.3.3.2第二种实现方式

在这里插入图片描述

  • 第一步:4小于6 向左寻找到2
  • 第二步:4大于2 向右寻找4为删除节点
  • 第三步:找到4节点左树中最大的节点3作为替换节点
  • 第四步:设置2的右节点为3(只替换节点本身,原右边5自动转化为节点3的右边节点)
  • 第五步:删除原来3节点中的3节点 剩余节点为3的左节点
  • 核心代码:
    //找到左树中的最大节点3代替4
    root.element = findMax(root.left).element; //找到3
    //删除原来3节点中的3节点 剩余节点为3的左节点
    root.left= remove(root.element, root.left);
    //root.right 还是原来的5

3.代码

3.1树节点

/**
 * 二叉树节点
 */
public class BinaryNode<T> {
    T element;
    BinaryNode<T> left;
    BinaryNode<T> right;

    public BinaryNode(T element) {
        this(element, null, null);
    }

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

3.2插入

public void insert(T x) {
        root = insert(x, root);
    }
/**
     * 添加节点
     *
     * @param x    插入节点
     * @param root 根节点
     */
    private BinaryNode<T> insert(T x, BinaryNode<T> root) {

        //如果根节点为空,则当前x节点为根节点
        if (null == root) {
            return new BinaryNode(x);
        }
      
        int compareResult = x.compareTo(root.element);

        //小于当前根节点 将x插入根节点的左边
        if (compareResult < 0) {
            root.left = insert(x, root.left);
        } else if (compareResult > 0) {
            //大于当前根节点 将x插入根节点的右边
            root.right = insert(x, root.right);
        } else {

        }
        return root;
    }

3.3删除

/**
     * 删除节点
     *
     * @param x    节点
     * @param root 根节点
     */
    private BinaryNode<T> remove(T x, BinaryNode<T> root) {

        if (null == root) {
            return root;
        }

        int compareResult = x.compareTo(root.element);

        //小于当前根节点
        if (compareResult < 0) {
            root.left = remove(x, root.left);
        } else if (compareResult > 0) {
            //大于当前根节点
            root.right = remove(x, 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;
    }

3.4 完整代码

public class BinarySearchTree<T extends Comparable<? super T>> {

    private BinaryNode<T> root;

    public void insert(T x) {
        root = insert(x, root);
    }

    public void remove(T x) {
        root = remove(x, root);
    }

    public T findMin() {
        return findMin(root).element;
    }


    public void makeEmpty() {
        root = null;
    }

    public boolean isEmpty() {
        return root == null;
    }

    /**
     * 添加节点
     *
     * @param x    插入节点
     * @param root 根节点
     */
    private BinaryNode<T> insert(T x, BinaryNode<T> root) {

        //如果根节点为空,则当前x节点为根及诶单
        if (null == root) {
            return new BinaryNode(x);
        }

        int compareResult = x.compareTo(root.element);

        //小于当前根节点 将x插入根节点的左边
        if (compareResult < 0) {
            root.left = insert(x, root.left);
        } else if (compareResult > 0) {
            //大于当前根节点 将x插入根节点的右边
            root.right = insert(x, root.right);
        } else {

        }
        return root;
    }

    /**
     * 删除节点
     *
     * @param x    节点
     * @param root 根节点
     */
    private BinaryNode<T> remove(T x, BinaryNode<T> root) {

        if (null == root) {
            return root;
        }

        int compareResult = x.compareTo(root.element);

        //小于当前根节点
        if (compareResult < 0) {
            root.left = remove(x, root.left);
        } else if (compareResult > 0) {
            //大于当前根节点
            root.right = remove(x, 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;
    }

    /**
     * 找最小节点
     *
     * @param root 根节点
     */
    private BinaryNode<T> findMin(BinaryNode<T> root) {
        if (root == null) {
            return null;
        } else if (root.left == null) {
            return root;
        }
        return findMin(root.left);
    }

    /**
     * 找最大节点
     *
     * @param root 根节点
     */
    private BinaryNode<T> findMax(BinaryNode<T> root) {
        if (root == null) {
            return null;
        } else if (root.right == null) {
            return root;
        } else {
            return findMax(root.right);
        }
    }

    public void printTree() {
        if (isEmpty()) {
            System.out.println("节点为空");
        } else {
            printTree(root);
        }
    }


    public void printTree(BinaryNode<T> root) {
        if (root != null) {
            System.out.print(root.element);
            if (null != root.left) {
                System.out.print("左边节点" + root.left.element);
            }
            if (null != root.right) {
                System.out.print("右边节点" + root.right.element);
            }
            System.out.println();
            printTree(root.left);
            printTree(root.right);
        }
    }

}

4.测试

代码:

 @Test
    public void test2(){
        BinarySearchTree testTree = new BinarySearchTree();
        testTree.insert(6);
        testTree.insert(2);
        testTree.insert(8);
        testTree.insert(1);
        testTree.insert(4);
        testTree.insert(3);
        testTree.insert(5);

        testTree.printTree();

        testTree.remove(2);

        System.out.println("======删除2节点之后======");

        testTree.printTree();
    }

测试截图:
在这里插入图片描述

5.参考书籍

《数据结构与算法分析》第三版

6.系列链接

下一篇:java实现AVL树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的记忆游戏(附源代码)   项目:JavaScript 记忆游戏(附源代码) 记忆检查游戏是一个使用 HTML5、CSS 和 JavaScript 开发的简单项目。这个游戏是关于测试你的短期 记忆技能。玩这个游戏 时,一系列图像会出现在一个盒子形状的区域中 。玩家必须找到两个相同的图像并单击它们以使它们消失。 如何运行游戏? 记忆游戏项目仅包含 HTML、CSS 和 JavaScript。谈到此游戏的功能,用户必须单击两个相同的图像才能使它们消失。 点击卡片或按下键盘键,通过 2 乘 2 旋转来重建鸟儿对,并发现隐藏在下面的图像! 如果翻开的牌面相同(一对),您就赢了,并且该对牌将从游戏中消失! 否则,卡片会自动翻面朝下,您需要重新尝试! 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,通过单击 memorygame-index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
查找(Binary Search Tree)是一种常见的数据结构,它的每个节点最多有两个子节点,左子节点的值小于父节点的值,右子节点的值大于父节点的值。Java 实现查找的代码如下: ``` public class BinarySearchTree { private Node root; private class Node { private int key; private Node left; private Node right; public Node(int key) { this.key = key; } } public void insert(int key) { root = insert(root, key); } private Node insert(Node x, int key) { if (x == null) { return new Node(key); } if (key < x.key) { x.left = insert(x.left, key); } else if (key > x.key) { x.right = insert(x.right, key); } return x; } public boolean contains(int key) { return contains(root, key); } private boolean contains(Node x, int key) { if (x == null) { return false; } if (key == x.key) { return true; } else if (key < x.key) { return contains(x.left, key); } else { return contains(x.right, key); } } public void delete(int key) { root = delete(root, key); } private Node delete(Node x, int key) { if (x == null) { return null; } if (key < x.key) { x.left = delete(x.left, key); } else if (key > x.key) { x.right = delete(x.right, key); } else { if (x.left == null) { return x.right; } else if (x.right == null) { return x.left; } else { Node t = x; x = min(t.right); x.right = deleteMin(t.right); x.left = t.left; } } return x; } private Node min(Node x) { if (x.left == null) { return x; } else { return min(x.left); } } private Node deleteMin(Node x) { if (x.left == null) { return x.right; } x.left = deleteMin(x.left); return x; } } ``` 这段代码实现了二查找的插入、查找和删除操作。其中,插入操作使用递归实现查找和删除操作也是递归实现的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值