• Java的二分搜索树


    定义

    二分搜索树是二叉树(不包含重复元素)。

    二分搜索树的每个节点的值,大于左子树的所有节点的值,小于其右子树的所有节点的值。

    每一棵子树也是二分搜索树。

    二叉树搜索树必须要有比较,继承Comparable类

    插入元素

    package com.dsideal;
    
    public class BST<E extends Comparable<E>> {
    
        private class Node
        {
            private E e;
            //左右孩子
            private Node left,right;
    
            public Node(E e)
            {
                this.e = e;
                left = null;
                right = null;
            }
    
        }
        //根节点
        private Node root;
        //二叉树元素个数
        private int size;
    
        private BST()
        {
            root = null;
            size = 0;
        }
    
        //二叉树有几个节点
        public int size()
        {
            return size;
        }
    
        //二叉树是否为空
        public boolean isEmpty()
        {
            return size == 0;
        }
    
        public void add(E e)
        {
            root = add(root,e);
        }
    
        //向根添加元素
        private Node add(Node node,E e)
        {
            if(node == null)
            {
                size ++;
                return new Node(e);
            }
    
            if (e.compareTo(node.e) < 0)
            {
                node.left = add(node.left,e);
            }else if(e.compareTo(node.e) > 0)
            {
                node.right = add(node.right,e);
            }
    
            return node;
        }
    
    }

     二分搜索树的前序遍历,访问该节点是在左右子树之前。

    private void preOrder(Node node)
        {
            if (node == null)
            {
                return;
            }
            System.out.println(node.e);
            preOrder(node.left);
            preOrder(node.right);
        }
    

     二分搜索树的中序遍历,结果是排序的。

     //二分搜索树的中序排序
        public void inOrder()
        {
            inOrder(root);
        }
    
        private void inOrder(Node node)
        {
            if (node == null)
            {
                return;
            }
            inOrder(node.left);
            System.out.println(node.e);
            inOrder(node.right);
        }

    二分搜索树的后序遍历

        //二分搜索树的后序遍历
        public void postOrder()
        {
            preOrder(root);
        }
    
        public void postOrder(Node node)
        {
            if (node == null)
            {
                return;
            }
            preOrder(node.left);
            preOrder(node.right);
            System.out.println(node.e);
        }

     二分搜索树前序遍历非递归实现

        public void preOrderNR()
        {
            Stack<Node> stack = new Stack<>();
            stack.push(root);
            while (!stack.isEmpty())
            {
                Node cur = stack.pop();
                System.out.println(cur.e);
                if (cur.right != null)
                {
                    stack.push(cur.right);
                }
                if (cur.left != null)
                {
                    stack.push(cur.left);
                }
            }
        }

     二分搜索树的层序遍历,最短路径

    public void levelOrder()
        {
            Queue<Node> queue = new LinkedList<>();
            queue.add(root);
            while (!queue.isEmpty())
            {
                Node cur = queue.remove();
                System.out.println(cur.e);
                if (cur.left != null)
                {
                    queue.add(cur.left);
                }
                if (cur.right != null)
                {
                    queue.add(cur.right);
                }
            }
        }

    重写toString

    @Override
        public String toString()
        {
            StringBuffer res = new StringBuffer();
            generateBSTString(root,0,res);
            return res.toString();
        }
    
        private void generateBSTString(Node node, int depth, StringBuffer res)
        {
            if (node == null)
            {
                res.append(generateBSTString(depth) + "null
    ");
                return;
            }
            res.append(generateBSTString(depth) + node.e + "
    ");
            generateBSTString(node.left,depth + 1,res);
            generateBSTString(node.right,depth + 1,res);
        }
    
        public String generateBSTString(int depth)
        {
            StringBuffer res = new StringBuffer(" ");
            for (int i = 0; i < depth; i++) {
                res.append("--");
            }
            return res.toString();
        }
    

     删除最大值和最小值

        //二分数的最大值
        public E maxNode()
        {
            if (isEmpty())
            {
                throw new IllegalArgumentException("BST is empty");
            }
            return maxNode(root).e;
        }
    
        private Node maxNode(Node node)
        {
            if (node.right == null)
            {
                return node;
            }
            return maxNode(node.right);
        }
        //二分数的最小值
        public E minNode()
        {
            if (isEmpty())
            {
                throw new IllegalArgumentException("BST is empty");
            }
            return minNode(root).e;
        }
    
        private Node minNode(Node node)
        {
            if (root.left == null)
            {
                return node;
            }
            return minNode(node.left);
        }
    
        public E removeMax()
        {
            E cur = maxNode();
            root = removeMax(root);
            return cur;
        }
        //删除最大值,返回根
        private Node removeMax(Node node)
        {
            if (node.right == null)
            {
                Node rightNode = node.left;
                node.left = null;
                size --;
                return rightNode;
            }
            node.right = removeMax(node.right);
            return node;
        }
    
        public E removeMin()
        {
            E cur = minNode();
            root = removeMin(root);
            return null;
        }
    
        private Node removeMin(Node node)
        {
            if (node.left == null)
            {
                Node leftNode = node.right;
                node.right = null;
                size--;
                return leftNode;
            }
            node.left = removeMin(node.left);
            return node;
        }

     删除节点

        //删除二分搜索树的节点
        private Node remove(Node node, E e)
        {
            if (node == null)
            {
                return null;
            }
            if (e.compareTo(node.e) < 0)
            {
                node.left = remove(node.left,e);
                return node;
            }else if (e.compareTo(node.e) > 0)
            {
                node.right = remove(node.right,e);
                return node;
            }else{
                if (node.right == null)
                {
                    Node leftNode = node.left;
                    node.left = null;
                    size --;
                    return leftNode;
                }
                if (node.left == null)
                {
                    Node righNode = node.right;
                    node.right = null;
                    size--;
                    return righNode;
                }
    
                Node successor = minNode(node.right);
                successor.right = removeMin(node.right);
                successor.left = node.left;
    
                node.right = node.left = null;
                return successor;
            }
    
        }
  • 相关阅读:
    poj3475
    poj2665
    poj2583
    poj2656
    【API进阶之路】破圈,用一个API代替10人内容团队
    除了方文山,用TA你也能帮周杰伦写歌词了
    敏捷转型谁先动:老总,项目经理or团队
    实战案例丨使用云连接CC和数据复制服务DRS实现跨区域RDS迁移和数据同步
    9块钱,构建个私有网盘,关键不限速
    终端传感了解吗?18个知识点为你扫盲
  • 原文地址:https://www.cnblogs.com/dslx/p/10403620.html
Copyright © 2020-2023  润新知