DS-二分搜索树

结构

在这里插入图片描述

  • 二分搜索树也叫二分查找树
  • 是在二叉树上做限制:左孩子小于当前节点的值,右孩子大于当前节点的值

MyBinarySearchTree

package BinarySearchTree;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * 二分搜索树
 */
public class BinarySearch<T extends Comparable<T>> {
    /**
     * 定义结点的结构
     */
    class Node {
        T val;
        Node left;
        Node right;

        public Node(T val) {
            this.val = val;
            this.left = this.right = null;
        }
    }

    /**
     * 定义根节点
     */
    private Node root;
    int size;

    public BinarySearch() {
        this.root = null;
    }

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

    /**
     * 向树中添加结点
     */
    public void add(T ele) {
        // 使用递归的方式添加结点
        root = add(root, ele);
        this.size++;
    }

    private Node add(Node root, T ele) {
        // 递归到底的情况(向下找节点为空)
        if (root == null) {
            return new Node(ele);
        }
        // 节点不为空,与节点大小做判断
        if (ele.compareTo(root.val) > 0) {
            root.right = add(root.right, ele);
        } else {
            root.left = add(root.left, ele);
        }
        return root;
    }

    /**
     * 从树中查找节点
     */
    public Node contains(T ele) {
        return contains(root, ele);
    }

    private Node contains(Node root, T ele) {
        // 递归到底的情况
        if (root == null) {
            return null;
        }
        // 递归操作
        T val = root.val;
        if (ele.compareTo(val) == 0) {
            return root;
        } else if (ele.compareTo(val) > 0) {
            return contains(root.right, ele);
        } else {
            return contains(root.left, ele);
        }
    }

    /**
     * 中序遍历
     */
    public List<T> middleOrder() {
        List<T> result = new ArrayList<>();
        middleOrder(root, result);
        return result;
    }

    private void middleOrder(Node root, List<T> result) {
        // 递归到底的情况
        if (root == null) {
            return;
        }
        // 先遍历左树,在获取中间值,然后遍历右树
        middleOrder(root.left, result);
        result.add(root.val);
        middleOrder(root.right, result);
    }

    /**
     * 前序遍历
     */
    public List<T> preOrder() {
        List<T> result = new ArrayList<>();
        preOrder(root, result);
        return result;
    }

    private void preOrder(Node root, List<T> result) {
        // 递归到底的情况
        if (root == null) {
            return;
        }
        // 先获取中间值,再遍历左树,然后遍历右树
        result.add(root.val);
        preOrder(root.left, result);
        preOrder(root.right, result);
    }

    /**
     * 后序遍历
     */
    public List<T> subOrder() {
        List<T> result = new ArrayList<>();
        subOrder(root, result);
        return result;
    }

    private void subOrder(Node root, List<T> result) {
        // 递归到底的情况
        if (root == null) {
            return;
        }
        // 先遍历左树,再遍历右树,然后获取中间值
        subOrder(root.left, result);
        subOrder(root.right, result);
        result.add(root.val);
    }

    /**
     * 层序编列(广度优先)
     */
    public List<T> layerOrder() {
        List<T> list = new ArrayList<>();
        if (root != null) {
            //按层依次入队,出队时让其左右子节点入队
            Queue<Node> queue = new LinkedList<>();
            queue.add(root);
            //队列不为空时就出队
            while (!queue.isEmpty()) {
                // 从队列中取出队首元素并加入 结果链表
                Node node = queue.poll();
                list.add(node.val);
                //让其左右子节点加入队列,再出队
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
        }
        return list;
    }

    /**
     * 查找最小结点
     */
    public T findMixNode() {
        if (root == null) {
            return null;
        }
        Node curNode = root;
        while (curNode.left != null) {
            curNode = curNode.left;
        }
        return curNode.val;
    }

    /**
     * 查找最小节点(递归)
     */
    public T findMixNodeDG() {
        if (root == null) {
            return null;
        }
        return findMixNodeDG(root).val;
    }

    private Node findMixNodeDG(Node root) {
        // 递归到底的情况
        if (root.left == null) {
            return root;
        }
        // 递归操作
        return findMixNodeDG(root.left);
    }

    /**
     * 删除最小结点
     */
    private void removeMixNode() {
        //先找到最小结点的值
        T mixNodeVal = findMixNodeDG();
        if (mixNodeVal == null) {
            System.out.println("the tree is empty");
            return;
        }
        System.out.println("Find mixNode value is " + mixNodeVal.toString());
        // 进行删除操作
        root = removeMixNode(root);
        this.size -= 1;
    }

    private Node removeMixNode(Node node) {
        if (node.left == null) {
            // 进行删除操作: 
            Node rightNode = node.right;
            node.right = null;
            return rightNode;
        }
        node.left = removeMixNode(node.left);
        return node;
    }

    /**
     * 删除任意节点
     */
    public void removeNode(T val) {
        if (root == null) {
            System.out.println("The tree is null");
            return;
        }
        // 查找结点
        Node node = findNodeDG(root, val);
        if (node != null) {
            //删除操作
            root = removeNode(root, val);
            this.size -= 1;
        }
    }

    private Node removeNode(Node node, T val) {
        // 递归到底的情况,找到了删除的结点
        if (node.val.compareTo(val) == 0) {
            if (node.left == null) {
                Node rightNode = node.right;
                node.right = null;
                return rightNode;
            } else if (node.right == null) {
                Node leftNode = node.left;
                node.left = null;
                return leftNode;
            } else {
                // 左右都不为空
                // 1、找node的后继(node.right中的最小结点)
                Node s = findMixNodeDG(node.right);
                // 2、从node.right中删除最小结点
                Node rightRoot = removeMixNode(node.right);
                // 3、使用后继结点替换node
                s.left = node.left;
                s.right = rightRoot;
                // 4、生成新树,新树的根节点就是后继结点,返回新树的根结点
                node.left = node.right = null;
                return s;
            }
        }
        // 递归操作
        if (node.val.compareTo(val) > 0) {
            node.left = removeNode(node.left, val);
        } else {
            node.right = removeNode(node.right, val);
        }
        return node;
    }

    // 查找任意结点
    private Node findNodeDG(Node node, T val) {
        // 找到最终还没有找到,就返回null
        if (node == null) {
            return null;
        }
        if (node.val.compareTo(val) == 0) {
            return node;
        } else if (node.val.compareTo(val) > 0) {
            return findNodeDG(node.left, val);
        } else {
            return findNodeDG(node.right, val);
        }
    }

    public int getSize() {
        return this.size;
    }

    @Override
    public String toString() {
        List<T> list = this.middleOrder();
        StringBuilder sb = new StringBuilder();
        list.forEach(item -> sb.append(item + " "));
        return sb.toString();
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

EnndmeRedis

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

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

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

打赏作者

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

抵扣说明:

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

余额充值