数据结构-二叉查找树(Binary Search Tree)

二叉查找树拥有如下特性:

  • 若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;
  • 若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
  • 左、右子树也分别为二叉查找树;
package com.zhuke.datastruct;

import com.alibaba.fastjson.JSON;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by ZHUKE on 2017/9/6.
 */
public class BSTUtils> {

    public static void main(String[] args) throws InterruptedException {
        BSTUtils BST = new BSTUtils<>();

        BinaryNode rootTree = null;

        rootTree = BST.insert(100, rootTree);
        rootTree = BST.insert(80, rootTree);
        rootTree = BST.insert(120, rootTree);
        rootTree = BST.insert(90, rootTree);
        rootTree = BST.insert(85, rootTree);
        rootTree = BST.insert(95, rootTree);
        rootTree = BST.insert(110, rootTree);
        rootTree = BST.insert(150, rootTree);
        rootTree = BST.insert(115, rootTree);
        rootTree = BST.insert(180, rootTree);
        rootTree = BST.insert(140, rootTree);

        BSTUtils BST1 = new BSTUtils<>();
        BinaryNode rootTree1 = null;

        rootTree1 = BST1.insertNoRecursive(-1, rootTree1);
        rootTree1 = BST1.insertNoRecursive(31, rootTree1);
        rootTree1 = BST1.insertNoRecursive(81, rootTree1);
        rootTree1 = BST1.insertNoRecursive(-36, rootTree1);
        rootTree1 = BST1.insertNoRecursive(188, rootTree1);
        rootTree1 = BST1.insertNoRecursive(-2, rootTree1);
        rootTree1 = BST1.insertNoRecursive(9, rootTree1);


        System.out.println("Search result = " + BST.search(100, rootTree).data);
        System.out.println("Search with no recursive result = " + BST.searchNoRecursive(100, rootTree).data);

        System.out.println("BST max value = " + BST.findMax(rootTree).data);
        System.out.println("BST min value = " + BST.findMin(rootTree).data);

        System.out.println("BST with no recursive max value = " + BST.findMaxNoRecursive(rootTree).data);
        System.out.println("BST with no recursive min value = " + BST.findMinNoRecursive(rootTree).data);

        ArrayList preOrderResult = new ArrayList<>();

        BST.preOrderTraversal(rootTree, preOrderResult);
        System.out.println("PreOrder traversal result = " + JSON.toJSONString(preOrderResult));

        preOrderResult.clear();
        BST.preOrderTraversalNoRecursive(rootTree, preOrderResult);
        System.out.println("PreOrder traversal with no recursive result = " + JSON.toJSONString(preOrderResult));

        ArrayList inOrderResult = new ArrayList<>();

        BST.inOrderTraversal(rootTree, inOrderResult);
        System.out.println("InOrder traversal result = " + JSON.toJSONString(inOrderResult));

        inOrderResult.clear();
        BST.inOrderTraversalNoRecursive(rootTree, inOrderResult);
        System.out.println("InOrder traversal with no recursive result = " + JSON.toJSONString(inOrderResult));

        ArrayList postOrderResult = new ArrayList<>();

        BST.postOrderTraversal(rootTree, postOrderResult);
        System.out.println("PostOrder traversal result = " + JSON.toJSONString(postOrderResult));

        postOrderResult.clear();
        BST.postOrderTraversalNoRecursive(rootTree, postOrderResult);
        System.out.println("PostOrder traversal with no recursive result = " + JSON.toJSONString(postOrderResult));

        ArrayList breadthResult = new ArrayList<>();

        BST.breadthTraversal(rootTree, breadthResult);
        System.out.println("Breadth traversal result = " + JSON.toJSONString(breadthResult));

        BST.delete(120, rootTree);

        Thread.sleep(Integer.MAX_VALUE);

    }


    /**
     * 在BST中插入一个数据值为data的节点
     *
     * @param data 数据值
     * @param tree 根节点
     * @return 插入了一个数据值为data的BST根节点
     */
    public BinaryNode insert(T data, BinaryNode tree) {
        if (tree == null) {
            tree = new BinaryNode<>(data, null, null, null);
            return tree;
        }
        int compareResult = data.compareTo(tree.data);
        if (compareResult < 0) {
            tree.leftNode = insert(data, tree.leftNode);
            tree.leftNode.parentNode = tree;
        } else if (compareResult > 0) {
            tree.rightNode = insert(data, tree.rightNode);
            tree.rightNode.parentNode = tree;
        } else {
            tree.count.incrementAndGet();
            return tree;
        }
        return tree;
    }

    /**
     * 使用非递归方式,在BST中插入一个数据值为data的节点
     *
     * @param data 数据值
     * @param tree 根节点
     * @return 插入了一个数据值为data的BST根节点
     */
    public BinaryNode insertNoRecursive(T data, BinaryNode tree) {
        if (tree == null) {
            tree = new BinaryNode<>(data, null, null, null);
            return tree;
        }
        int compareResult = data.compareTo(tree.data);
        if (compareResult == 0) {
            tree.count.incrementAndGet();
            return tree;
        } else {
            BinaryNode targetInsertLocation = compareResult > 0 ? tree.rightNode : tree.leftNode;
            if (targetInsertLocation == null) {
                if (compareResult > 0) {
                    tree.rightNode = new BinaryNode<>(data, null, null, tree);
                } else {
                    tree.leftNode = new BinaryNode<>(data, null, null, tree);
                }
                return tree;
            }
            //循环遍历到树的末端节点,判断处理插入的正确位置
            while (true) {
                compareResult = data.compareTo(targetInsertLocation.data);
                if (compareResult == 0) {
                    targetInsertLocation.count.incrementAndGet();
                    return tree;
                } else {
                    if (compareResult > 0) {
                        if (targetInsertLocation.rightNode != null) {
                            targetInsertLocation = targetInsertLocation.rightNode;
                        } else {
                            targetInsertLocation.rightNode = new BinaryNode<>(data, null, null, targetInsertLocation);
                            return tree;
                        }
                    } else {
                        if (targetInsertLocation.leftNode != null) {
                            targetInsertLocation = targetInsertLocation.leftNode;
                        } else {
                            targetInsertLocation.leftNode = new BinaryNode<>(data, null, null, targetInsertLocation);
                            return tree;
                        }
                    }
                }
            }
        }
    }

    /**
     * 删除节点值为data的节点
     *
     * @param data 数据值
     * @param tree 根节点
     * @return 删除节点值为data后的BST
     */
    public BinaryNode delete(T data, BinaryNode tree) {

        BinaryNode searchedNode = search(data, tree);

        if (searchedNode == null) {
            return tree;
        }

        //叶子节点,直接删除
        if (searchedNode.leftNode == null && searchedNode.rightNode == null) {
            int parentLeftCompareResult = searchedNode.parentNode.leftNode.data.compareTo(data);
            searchedNode.parentNode = null;
            if (searchedNode.count.decrementAndGet() == 0) {
                //只有一个元素,直接删除关联关系
                if (parentLeftCompareResult == 0) {
                    searchedNode.leftNode = null;
                } else {
                    searchedNode.rightNode = null;
                }
            }
        } else if (searchedNode.leftNode != null && searchedNode.rightNode != null) {//同时有左子树和右子树
            //找到替代被删除节点的节点,该节点需要比被删除节点的左子树都大,比右子树都小
            //被删除节点的右子树的最小值,满足上述要求,而且该节点一定是叶子节点
            BinaryNode replacedNode = findMin(searchedNode.rightNode);
            searchedNode.data = replacedNode.data;
            //替换完成后,直接删除
            replacedNode.parentNode.leftNode = null;
            replacedNode.parentNode = null;
        } else {
            /*只有左子树或右子树*/
            if (searchedNode.leftNode != null) {
                //只有左子树,将左子树和父结点相连接
                int searchedNodeCompareToParentNode = searchedNode.data.compareTo(searchedNode.parentNode.data);
                if (searchedNodeCompareToParentNode > 0) {
                    //被删除的节点为父结点的右节点
                    searchedNode.parentNode.rightNode = searchedNode.leftNode;
                } else {
                    searchedNode.parentNode.leftNode = searchedNode.leftNode;
                }
            } else {
                //只有右子树,将右子树和父节点想相连接
                int searchedNodeCompareToParentNode = searchedNode.data.compareTo(searchedNode.parentNode.data);
                if (searchedNodeCompareToParentNode > 0) {
                    //被删除的节点为父结点的右节点
                    searchedNode.parentNode.rightNode = searchedNode.rightNode;
                } else {
                    searchedNode.parentNode.leftNode = searchedNode.rightNode;
                }
            }
        }
        return tree;
    }

    /**
     * 查找指定值在BST中的所在节点
     *
     * @param data 数据值
     * @param tree 根节点
     * @return 节点值为data的节点
     */
    public BinaryNode search(T data, BinaryNode tree) {
        if (tree == null) {
            return null;
        }
        int compareResult = data.compareTo(tree.data);
        if (compareResult > 0) {
            return search(data, tree.rightNode);
        } else if (compareResult < 0) {
            return search(data, tree.leftNode);
        } else {
            return tree;
        }
    }

    /**
     * 非递归方式,查找指定值在BST中的所在节点
     *
     * @param data 数据值
     * @param tree 根节点
     * @return 节点值为data的节点
     */
    public BinaryNode searchNoRecursive(T data, BinaryNode tree) {
        if (tree == null) {
            return null;
        }
        int compareResult = data.compareTo(tree.data);
        if (compareResult == 0) {
            return tree;
        } else {
            BinaryNode targetNodeLocation = compareResult > 0 ? tree.rightNode : tree.leftNode;
            //遍历查找树的各层节点
            while (targetNodeLocation != null) {
                compareResult = data.compareTo(targetNodeLocation.data);
                if (compareResult == 0) {
                    return targetNodeLocation;
                } else {
                    targetNodeLocation = (compareResult > 0 ? targetNodeLocation.rightNode : targetNodeLocation.leftNode);
                }
            }
            return null;
        }
    }

    /**
     * 查找BST的最小值
     *
     * @param tree 根节点
     * @return BST中的最小值
     */
    public BinaryNode findMin(BinaryNode tree) {
        if (tree == null) {
            return null;
        }
        if (tree.leftNode == null) {
            return tree;
        } else {
            return findMin(tree.leftNode);
        }
    }

    public BinaryNode findMinNoRecursive(BinaryNode tree) {
        if (tree == null) {
            return null;
        }
        if (tree.leftNode == null) {
            return tree;
        } else {
            BinaryNode targetNodeLocation = tree.leftNode;
            while (true) {
                if (targetNodeLocation.leftNode == null) {
                    return targetNodeLocation;
                } else {
                    targetNodeLocation = targetNodeLocation.leftNode;
                }
            }
        }
    }

    /**
     * 查找BST的最大值
     *
     * @param tree 根节点
     * @return BST中的最大值
     */
    public BinaryNode findMax(BinaryNode tree) {
        if (tree == null) {
            return null;
        }
        if (tree.rightNode == null) {
            return tree;
        } else {
            return findMax(tree.rightNode);
        }
    }

    public BinaryNode findMaxNoRecursive(BinaryNode tree) {
        if (tree == null) {
            return null;
        }
        if (tree.rightNode == null) {
            return tree;
        } else {
            BinaryNode targetNodeLocation = tree.rightNode;
            while (true) {
                if (targetNodeLocation.rightNode == null) {
                    return targetNodeLocation;
                } else {
                    targetNodeLocation = targetNodeLocation.rightNode;
                }
            }
        }
    }

    /**
     * 前序遍历BST
     *
     * @param tree            BST根节点
     * @param traversalResult 遍历结果
     */
    public void preOrderTraversal(BinaryNode tree, List traversalResult) {
        if (tree != null) {
            addTraversalToResultList(tree, traversalResult);
            preOrderTraversal(tree.leftNode, traversalResult);
            preOrderTraversal(tree.rightNode, traversalResult);
        }
    }

    /**
     * 非递归方式前序遍历BST
     *
     * @param tree            BST根节点
     * @param traversalResult 遍历结果
     */
    public void preOrderTraversalNoRecursive(BinaryNode tree, List traversalResult) {
        if (tree != null) {
            //使用一个栈,暂存访问左右子树的顺序
            Stack> stack = new Stack<>();
            BinaryNode node = tree;

            while (node != null || !stack.isEmpty()) {

                //首先访问根节点,并将根节点入栈,因为需要通过根节点进入相应的左右子树
                while (node != null) {
                    addTraversalToResultList(node.clone(), traversalResult);
                    stack.push(node);
                    node = node.leftNode;
                }
                //上面的循环全部访问左子树的所有根节点,直到BST的最左下角,此时情况如下
                /*
                        x                   top_node

                        /                   /       \

                     top_node          node=null    right_node

                     /     \

                node=null   null

                */
                //因此无论何种情况都需要出栈,因为此时top_node的根节点和左叶子节点都已经完全访问,
                // 所以按照相同步骤遍历访问其右子树
                if (!stack.isEmpty()) {
                    node = stack.pop();
                    node = node.rightNode;
                }
            }
        }
    }

    /**
     * 中序遍历BST
     *
     * @param tree            BST根节点
     * @param traversalResult 遍历结果
     */
    public void inOrderTraversal(BinaryNode tree, List traversalResult) {
        if (tree != null) {
            inOrderTraversal(tree.leftNode, traversalResult);
            addTraversalToResultList(tree, traversalResult);
            inOrderTraversal(tree.rightNode, traversalResult);
        }
    }

    /**
     * 非递归方式中序遍历BST
     *
     * @param tree            BST根节点
     * @param traversalResult 遍历结果
     */
    public void inOrderTraversalNoRecursive(BinaryNode tree, List traversalResult) {
        if (tree != null) {
            //使用一个栈,暂存访问左右子树的顺序
            Stack> stack = new Stack<>();
            BinaryNode node = tree;

            while (node != null || !stack.isEmpty()) {

                //一直遍历到左子树最左下角,边遍历边保存根节点到栈中
                //需要借助保存的根节点进入右节点的遍历过程
                while (node != null) {
                    stack.push(node);
                    node = node.leftNode;
                }
                //此时位于栈顶的元素有如下两种情况,无论哪种情况都应将栈顶节点出栈,访问该节点
                /*
                        x                   top_node

                        /                   /       \

                     top_node          node=null    right_node

                     /     \

                node=null   null

                */

                // 此时可以进行访问栈顶元素
                if (!stack.isEmpty()) {
                    node = stack.pop();
                    addTraversalToResultList(node.clone(), traversalResult);
                    //如果访问节点的根节点有右子树,则进行上层循环,中序遍历访问右子树的节点
                    node = node.rightNode;
                }
            }

        }
    }

    /**
     * 后序遍历BST
     *
     * @param tree            BST根节点
     * @param traversalResult 遍历结果
     */
    public void postOrderTraversal(BinaryNode tree, List traversalResult) {
        if (tree != null) {
            postOrderTraversal(tree.leftNode, traversalResult);
            postOrderTraversal(tree.rightNode, traversalResult);
            addTraversalToResultList(tree, traversalResult);
        }
    }

    /**
     * 非递归方式,后序遍历BST
     *
     * @param tree            BST根节点
     * @param traversalResult 遍历结果
     */
    public void postOrderTraversalNoRecursive(BinaryNode tree, List traversalResult) {
        if (tree != null) {
            //记录原BST的左右子树访问顺序
            Stack> stack = new Stack<>();
            //记录后续遍历的遍历顺序
            Stack> output = new Stack<>();

            stack.push(tree);
            while (!stack.isEmpty()) {
                BinaryNode pop = stack.pop();

                //将根节点首先入栈到output栈底,根节点最后访问
                output.push(pop);
                if (pop.leftNode != null) {
                    //leftNode节点先入栈stack,后入output栈,符合left-right-root的访问顺序
                    stack.push(pop.leftNode);
                }
                if (pop.rightNode != null) {
                    //right节点后入栈stack,先入output栈,符合left-right-root的访问顺序
                    stack.push(pop.rightNode);
                }
            }

            while (!output.isEmpty()) {
                addTraversalToResultList(output.pop(), traversalResult);
            }
        }
    }

    /**
     * 广度优先遍历
     *
     * @param tree            BST
     * @param traversalResult 遍历结果
     */
    public void breadthTraversal(BinaryNode tree, List traversalResult) {
        Queue> queue = new LinkedList<>();
        queue.add(tree);
        while (!queue.isEmpty()) {
            BinaryNode node = queue.remove();
            addTraversalToResultList(node, traversalResult);
            if (node.leftNode != null) {
                queue.add(node.leftNode);
            }
            if (node.rightNode != null) {
                queue.add(node.rightNode);
            }
        }
    }

    /**
     * 对二叉排序树进行升序排序,即是对BST进行中序遍历的结果
     *
     * @param tree       根节点
     * @param sortedData 升序排序的结果
     */
    public void sort(BinaryNode tree, List sortedData) {
        inOrderTraversal(tree, sortedData);
    }


    private void addTraversalToResultList(BinaryNode node, List traversalResult) {
        for (int i = 0; i < node.count.intValue(); i++) {
            traversalResult.add(node.data);
        }
    }

}

/**
 * 二叉查找树的节点数据结构
 *
 * @param  数据节点的类型,必须实现Comparable接口
 */
class BinaryNode> {
    /**
     * 数据类型
     */
    T data;

    /**
     * 左节点
     */
    BinaryNode leftNode;

    /**
     * 右节点
     */
    BinaryNode rightNode;

    /**
     * 父节点
     */
    BinaryNode parentNode;

    /**
     * 数据data出现的次数,
     * 用于支持BST可以插入相同data的值,
     * 以便节点数据值的比较
     */
    AtomicInteger count;


    public BinaryNode(T data) {
        this.data = data;
    }

    public BinaryNode(T data, BinaryNode leftNode, BinaryNode rightNode, BinaryNode parentNode) {
        this.data = data;
        this.leftNode = leftNode;
        this.rightNode = rightNode;
        this.parentNode = parentNode;
        this.count = new AtomicInteger(1);
    }

    @Override
    protected BinaryNode clone() {
        BinaryNode clonedNode = new BinaryNode<>(this.data, null, null, null);
        clonedNode.count = new AtomicInteger(this.count.intValue());
        return clonedNode;
    }
}

你可能感兴趣的:(数据结构-二叉查找树(Binary Search Tree))