二叉搜索树

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);
        }

    }

}
原文地址:https://www.cnblogs.com/lfdestiny/p/9572734.html