zoukankan      html  css  js  c++  java
  • 二叉搜索树

    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.Stack;
    
    /**
     * @Auther: Administrator
     * @Date: 2018/8/31 08:55
     * @Description: BinarySearchTree
     */
    public class BinarySearchTree<Key extends Comparable, Value> {
    
        //私有化节点类
        private class Node {
            private Key key;
            private Value value;
            private Node left;
            private Node right;
    
            Node(Key key, Value value) {
                this.key = key;
                this.value = value;
                this.left = null;
                this.right = null;
            }
        }
    
        /**
         * BinarySearchTree 根节点
         */
        private Node root;
    
        /**
         * BinarySearchTree节点个数
         */
        private int count;
    
        /**
         * 默认构造一个空的BinarySearchTree
         */
        public BinarySearchTree() {
            this.root = null;
            count = 0;
        }
    
        /**
         * @return 返回BinarySearchTree节点个数
         */
        public int size() {
            return count;
        }
    
        /**
         * @return 返回二叉搜索树是否为空
         */
        public boolean isEmpty() {
            return count == 0;
        }
    
        /**
         * 二叉搜索树中插入元素
         *
         * @param key   键
         * @param value 值
         */
        public void insert(Key key, Value value) {
            root = insert(root, key, value);
        }
    
        /**
         * @param key 键
         * @return 返回BinarySearchTree中是否包含键
         */
        public boolean contain(Key key) {
            return contain(root, key);
        }
    
        /**
         * @param key 键
         * @return 返回BinarySearchTree中对应Key的Value
         */
        public Value search(Key key) {
            return search(root, key);
        }
    
        /**
         * 前序遍历(递归)
         */
        public void preOrder() {
            preOrder(root);
        }
    
        /**
         * 中序遍历(递归)
         */
        public void inOrder() {
            inOrder(root);
        }
    
        /**
         * 后序遍历(递归)
         */
        public void postOrder() {
            postOrder(root);
        }
    
        /**
         * 前序遍历(非递归)
         */
        public void preOrderRec(){
            preOrderRec(root);
        }
    
        /**
         * 中序遍历(非递归)
         */
        public void inOrderRec(){
            inOrderRec(root);
        }
    
        /**
         * 后续遍历(非递归)
         *
         *
         *     后序遍历递归定义:先左子树,后右子树,再根节点。
         *     后序遍历的难点在于:需要判断上次访问的节点是位于左子树,还是右子树。
         *  若是位于左子树,则需跳过根节点,先进入右子树,再回头访问根节点;
         *     若是位于右子树,则直接访问根节点。
         *
         * 
         */
        public void postOrderRec(){
            postOrderRec(root);
        }
    
        /**
         * 层序遍历
         */
        public void levelOrder() {
    
            Queue<Node> queue = new LinkedList<Node>();
            queue.add(root);
            while (!queue.isEmpty()) {
    
                Node node = queue.remove();
    
                System.out.println(node.key);
                if (node.left != null) {
                    queue.add(node.left);
                }
                if (node.right != null) {
                    queue.add(node.right);
                }
    
            }
    
        }
    
    
    
        private void preOrder(Node node) {
            if (node != null) {
                System.out.print(node.key + "	");
                preOrder(node.left);
                preOrder(node.right);
            }
        }
    
        private void preOrderRec(Node root) {
    
            Stack<Node> stack = new Stack<Node>();
            if (root!=null){
                stack.push(root);
            }
    
            while (!stack.isEmpty()){
                Node node = stack.pop();
                System.out.print(node.key + "	");
                if (node.right!=null)stack.push(node.right);
                if (node.left!=null)stack.push(node.left);
            }
    
        }
    
    
        private void inOrder(Node node) {
            if (node != null) {
                inOrder(node.left);
                System.out.print(node.key + "	");
                inOrder(node.right);
            }
        }
    
        private void inOrderRec(Node root) {
    
            Stack<Node> stack = new Stack<>();
    
            while(!stack.isEmpty() || root != null){
                while(root != null){
                    stack.push(root);
                    root = root.left;
                }
    
                if (!stack.isEmpty()){
                    Node node = stack.pop();
                    System.out.print(node.key+"	");
                    root = node.right;
                }
            }
    
        }
    
        private void postOrder(Node node) {
            if (node != null) {
                postOrder(node.left);
                postOrder(node.right);
                System.out.print(node.key + "	");
            }
        }
    
        private void postOrderRec(Node node){
    
            Stack<Node> stack = new Stack<Node>();
    
            //记录当前访问节点
            Node curNode = node;
            //记录最后访问节点
            Node lastVisitNode = null;
            //把所有左节点入栈
            while(curNode!=null){
                stack.push(curNode);
                curNode = curNode.left;
            }
    
            while (!stack.isEmpty()){
                //弹出栈顶元素
                curNode = stack.pop();
                //一个根节点被访问的前提是:无右节点,或者,右节点已经被访问
                if(curNode.right!=null&&curNode.right!=lastVisitNode){
                    //根节点重新入栈
                    stack.push(curNode);
                    //进入右子树,且可以肯定右子树一定不为空
                    curNode = curNode.right;
                    while (curNode!=null){
                        //在走进右子树最左边
                        stack.push(curNode);
                        curNode = curNode.left;
                    }
                }else{
                    //访问
                    System.out.print(curNode.key+"	");
                    //修改最近被访问的节点
                    lastVisitNode = curNode;
                }
    
            }
    
        }
    
    
    
        private Value search(Node node, Key key) {
    
            if (node == null) {
                return null;
            }
    
            if (key.compareTo(node.key) == 0) {
                return node.value;
            } else if (key.compareTo(node.key) < 0) {
                return search(node.left, key);
            } else {
                return search(node.right, key);
            }
    
        }
    
        //插入元素
        private Node insert(Node node, Key key, Value value) {
    
            //如果节点为null,则创建新节点并插入对应位置
            if (node == null) {
                count++;
                return new Node(key, value);
            }
    
            //如果BinarySearchTree中存才相应的键,则替换该键对应的值
            if (key.compareTo(node.key) == 0) {
                node.value = value;
            } else if (key.compareTo(node.key) < 0) {//如果BinarySearchTree中key大于新插入的key,则去Tree中左子树查找相应位置
                node.left = insert(node.left, key, value);
            } else if (key.compareTo(node.key) > 0) {//如果BinarySearchTree中key小于新插入的key,则去Tree中右子树查找相应位置
                node.right = insert(node.right, key, value);
            }
    
            return node;
    
        }
    
        private boolean contain(Node node, Key key) {
    
            if (node == null) {
                return false;
            }
    
            if (key.compareTo(node.key) == 0) {
                return true;
            } else if (key.compareTo(node.key) < 0) {
                return contain(node.left, key);
            } else {
                return contain(node.right, key);
            }
    
        }
    
    }
  • 相关阅读:
    ERP SYSTEM 开发指南(一)简单模块开发
    机器学习--决策树
    机器学习---线性模型
    机器学习
    《IDA Pro 权威指南》学习
    内核漏洞利用技术
    word2vec、seq2seq
    Ring0级的探索
    ActiveX 控件的漏洞挖掘
    FTP的漏洞挖掘
  • 原文地址:https://www.cnblogs.com/lfdestiny/p/9572734.html
Copyright © 2011-2022 走看看