排序专题(二) / 稳定的内部排序 / 二叉排序树

  • 二叉排序树还是很容易理解的,无需多讲解,定义:
    • 若左子树不空,则左子树上所有结点的值均小于它的根结点的值
    • 若右子树不空,则右子树上所有结点的值均大于它的根结点的值
    • 左、右子树也分别为二叉排序树
  • 代码较多,注释较少,不过还是比较易懂的,但逻辑不一定是最简洁的
  • Code除delete()方法外,其它都经过UT测试
  • 方法列表:
    • 获取树中元素总个数,重复元素也计数:public int size();
    • 获取树的高度,即层数:public int depth();
    • 通过给定数组构建二叉排序树:public void buildBinarySortTree(int[] array);
    • 添加一个元素:public boolean add(int data);
    • 删除一个元素,若所给值对应多个元素,会一并删除:public boolean delete(int value);
    • 获取指定元素的前驱:public Integer[] getPrecursor(int value);
    • 按给定值搜索元素:public boolean search(int value);

    • 递归的先序遍历:private void preorderTraversalRecursion(Node root);
    • 非递归的先序遍历A:public int[] preorderTraversal();
    • 非递归的先序遍历B:public int[] anotherPreorderTraversal();

    • 递归的中序遍历:private void inorderTraversalRecursion(Node root);
    • 非递归的中序遍历:public int[] inorderTraversal();

    • 递归的后序遍历:private void postorderTraversalRecursion(Node root);
    • 非递归的后序遍历A:public int[] postorderTraversalA();
    • 非递归的后序遍历B:public int[] postorderTraversalB();
    • 非递归的后序遍历C:public int[] postorderTraversalC();

    • 非递归层序遍历A:public int[] levelOrderTraversal();
    • 非递归的层序遍历B:public int[] anotherLevelOrderTraversal();
  • public class BinarySortTree {
        
        private transient int size = 0;
        private transient int depth = 0;
        
        private Node root = null;
        
        private List<Integer> builtinPreorderList = null;
        private List<Integer> builtinInorderList = null;
        private List<Integer> builtinPostorderList = null;
        
        /*
         * The structure of the tree Node
         */
        private static class Node {
            
            private Integer data;
            private Integer equivalent;
          
            private Node parentNode;
            private Node leftChild;
            private Node rightChild;
            
            public Node(Integer data, Integer equivalent,
                    Node parentNode, Node leftChild, Node rightChild) {
                
                this.data = data;
                this.equivalent = equivalent;
                this.parentNode = parentNode;
                this.leftChild = leftChild;
                this.rightChild = rightChild;
            }
    
        }
        
        public BinarySortTree() {
            root = new Node(null, null, null, null, null);
            builtinPreorderList = new ArrayList<Integer>();
            builtinInorderList = new ArrayList<Integer>();
            builtinPostorderList = new ArrayList<Integer>();
        }
        
        public int size() {
            return size;
        }
        
        public int depth() {
            return depth;
        }
        
        public void buildBinarySortTree(int[] array) {
            
            for (int i = 0; i < array.length; i++) {
                add(array[i]);
            }
            
        }
        
        public boolean add(int data) {
            
            if (size == 0) {
                root.data = data;
                root.equivalent = 0;
                size ++;
                depth ++;
                return true;
            }
            
            Node tempNode = root;
            
            int tempDepth = 1;
            
            while (true) {
                
                if (data < tempNode.data) {
                    if (tempNode.leftChild != null) {
                        tempNode = tempNode.leftChild;
                        tempDepth ++;
                    } else {
                        tempNode.leftChild = new Node(data, 0, tempNode, null, null);
                        tempDepth ++;
                        break;
                    }
                } else if (data == tempNode.data) {
                    tempNode.equivalent ++;
                    size ++;
                    return true;
                } else {
                    if (tempNode.rightChild != null) {
                        tempNode = tempNode.rightChild;
                        tempDepth ++;
                    } else {
                        tempNode.rightChild = new Node(data, 0, tempNode, null, null);
                        tempDepth ++;
                        break;
                    }
                }
                
            }
            
            size ++;
            
            if (tempDepth > depth) {
                depth = tempDepth;
            }
            
            return true;
        }
        
        public boolean delete(int value) {
            
            Node resultNode = searchNode(value);
            
            if (resultNode == null) {
                return false;
            } else {
                if (resultNode.leftChild == null) {
                    if (resultNode.rightChild == null) {
                        /*
                         * Both leftChild and rightChild are null
                         */
                        if (resultNode.data < resultNode.parentNode.data) {
                            resultNode.parentNode.leftChild = null;
                        } else {
                            resultNode.parentNode.rightChild = null;
                        }
                    } else {
                        /*
                         * leftChild is null but rightChile is not null
                         */
                        if (resultNode.data < resultNode.parentNode.data) {
                            resultNode.parentNode.leftChild = resultNode.leftChild;
                            resultNode.leftChild.parentNode = resultNode.parentNode;
                        }
                    }
                } else {
                    if (resultNode.rightChild == null) {
                        /*
                         * leftChild is not null but rightChild is null
                         */
                        if (resultNode.data < resultNode.parentNode.data) {
                            resultNode.parentNode.leftChild = resultNode.leftChild;
                            resultNode.leftChild.parentNode = resultNode.parentNode;
                        } else {
                            resultNode.parentNode.rightChild = resultNode.leftChild;
                            resultNode.leftChild.parentNode = resultNode.parentNode;
                        }
                    } else {
                        /*
                         * Both leftChild and rightChild are not null
                         */
                        Node tempNode = resultNode.rightChild;
                        while (tempNode.leftChild != null) {
                            tempNode = tempNode.leftChild;
                        }
                        resultNode.data = tempNode.data;
                        resultNode.equivalent = tempNode.equivalent;
                        if (tempNode.equals(resultNode.rightChild)) {
                            /*
                             * The condition that the resultNode's rightChild
                             * has not leftChild
                             */
                            resultNode.rightChild = tempNode.rightChild;
                        } else {
                            /*
                             * The condition that the resultNode's rightChild
                             * has leftChild
                             */
                            tempNode.parentNode.leftChild = tempNode.rightChild;
                        }
                        if (tempNode.rightChild != null) {
                            /*
                             * Rebuild the relation from childNode to parentNode
                             */
                            tempNode.rightChild.parentNode = tempNode.parentNode;
                        }
                    }
                }
                return true;
            }
            
        }
        
        private Node searchNode(int value) {
            
            Node resultNode = root;
            
            while (resultNode != null && value != resultNode.data) {
                if (value < resultNode.data) {
                    resultNode = resultNode.leftChild;
                } else {
                    resultNode = resultNode.rightChild;
                }
            }
            
            return resultNode;
        }
        
        /**
         * Get the informations of the anterior node of the corresponding node
         * which contains the given data, main are the data and its number.
         * 
         * @return An array, details as follows :
         * 
         *     [0] --> the data of the anterior node.
         *     [1] --> the quantity of this data.
         *     
         *     [null, null] --> this tree does not contain the given value.
         */
        public Integer[] getPrecursor(int value) {
            
            Node resultNode = searchNode(value);
            
            if (resultNode == null || resultNode.equals(root)) {
                return new Integer[] {null, null};
            } else {
                return new Integer[] {resultNode.parentNode.data,
                        resultNode.parentNode.equivalent};
            }
            
        }
        
        public boolean search(int value) {
            
            Node resultNode = searchNode(value);
            
            if (resultNode == null) {
                return false;
            } else {
                return true;
            }
        }
        
        /*
         * Recursively get the binary sort tree's sequence according to the given way.
         */
        public int[] getSpecifiedTraversalSequenceRecursion(String type) {
            int[] resultArray = new int[size];
            int index = 0;
            switch (type) {
                case Constant.TREE_TRAVERSAL_PREORDER :
                    preorderTraversalRecursion(root);
                    for (int element : builtinPreorderList) {
                        resultArray[index ++] = element;
                    }
                    break;
                case Constant.TREE_TRAVERSAL_INORDER :
                    inorderTraversalRecursion(root);
                    for (int element : builtinInorderList) {
                        resultArray[index ++] = element;
                    }
                    break;
                case Constant.TREE_TRAVERSAL_POSTORDER :
                    postorderTraversalRecursion(root);
                    for (int element : builtinPostorderList) {
                        resultArray[index ++] = element;
                    }
                    break;
            }
            return resultArray;
        }
        
        /*
         * The tree's recursive preorder traversal.
         */
        private void preorderTraversalRecursion(Node root) {
            if (root == null) {
                return;
            } else {
                for (int i = root.equivalent; i >= 0; i --) {
                    builtinPreorderList.add(root.data);
                }
                preorderTraversalRecursion(root.leftChild);
                preorderTraversalRecursion(root.rightChild);
            }
        }
        
        /*
         * The tree's nonrecursive preorder traversal.
         */
        public int[] preorderTraversal() {
            
            int[] resultArray = new int[size];
            
            int index = 0;
            
            Stack<Node> assistanceStack = new Stack<Node>();
            
            Node tempNode = root;
            
            while (tempNode != null || !assistanceStack.empty()) {
                if (tempNode != null) {
                    for (int i = tempNode.equivalent; i >= 0; i --) {
                        resultArray[index ++] = tempNode.data;
                    }
                    assistanceStack.push(tempNode);
                    tempNode = tempNode.leftChild;
                } else {
                    tempNode = assistanceStack.pop();
                    tempNode = tempNode.rightChild;
                }
            }
            
            return resultArray;
        }
        
        /*
         * The tree's another nonrecursive preorder traversal.
         */
        public int[] anotherPreorderTraversal() {
            
            int[] resultArray = new int[size];
            
            if (size != 0) {
                
                int index = 0;
                
                Stack<Node> assistanceStack = new Stack<Node>();
                
                assistanceStack.push(root);
                
                while (!assistanceStack.empty()) {
                    Node tempNode = assistanceStack.pop();
                    for (int i = tempNode.equivalent; i >= 0; i --) {
                        resultArray[index ++] = tempNode.data;
                    }
                    if (tempNode.rightChild != null) {
                        assistanceStack.push(tempNode.rightChild);
                    }
                    if (tempNode.leftChild != null) {
                        assistanceStack.push(tempNode.leftChild);
                    }
                }
            }
            
            return resultArray;
        }
        
        /*
         * The tree's recursive inorder traversal.
         */
        private void inorderTraversalRecursion(Node root) {
            if (root == null) {
                return;
            } else {
                inorderTraversalRecursion(root.leftChild);
                for (int i = root.equivalent; i >= 0; i --) {
                    builtinInorderList.add(root.data);
                }
                inorderTraversalRecursion(root.rightChild);
            }
        }
        
        /*
         * The tree's nonrecursive inorder traversal.
         */
        public int[] inorderTraversal() {
            
            int[] resultArray = new int[size];
            
            int index = 0;
            
            Stack<Node> assistanceStack = new Stack<Node>();
            
            Node tempNode = root;
            
            while (tempNode != null || !assistanceStack.empty()) {
                if (tempNode != null) {
                    assistanceStack.push(tempNode);
                    tempNode = tempNode.leftChild;
                } else {
                    tempNode = assistanceStack.pop();
                    for (int i = tempNode.equivalent; i >= 0; i --) {
                        resultArray[index ++] = tempNode.data;
                    }
                    tempNode = tempNode.rightChild;
                }
            }
            
            return resultArray;
        }
        
        /*
         * The tree's recursive postorder traversal.
         */
        private void postorderTraversalRecursion(Node root) {
            if (root == null) {
                return;
            } else {
                postorderTraversalRecursion(root.leftChild);
                postorderTraversalRecursion(root.rightChild);
                for (int i = root.equivalent; i >= 0; i --) {
                    builtinPostorderList.add(root.data);
                }
            }
        }
        
        public int[] postorderTraversalA() {
            int[] resultArray = new int[size];
            if (size != 0) {
                int index = 0;
                Node tempNode = root;
                Node lastVisitedNode = null;
                Stack<Node> assistanceStack = new Stack<Node>();
                while (tempNode != null) {
                    while (tempNode.leftChild != null) {
                        assistanceStack.push(tempNode);
                        tempNode = tempNode.leftChild;
                    }
                    while (tempNode != null
                            && (tempNode.rightChild == null
                            || tempNode.rightChild == lastVisitedNode)) {
                        for (int i = tempNode.equivalent; i >= 0; i --) {
                            resultArray[index ++] = tempNode.data;
                        }
                        lastVisitedNode = tempNode;
                        if (assistanceStack.isEmpty()) {
                            return resultArray;
                        }
                        tempNode = assistanceStack.pop();
                    }
                    assistanceStack.push(tempNode);
                    tempNode = tempNode.rightChild;
                }
            }
            
            return resultArray;
        }
        
        public int[] postorderTraversalB() {
            int[] resultArray = new int[size];
            if (size > 0) {
                int index = 0;
                Node tempNode = root;
                Node rightChild = null;
                Stack<Node> leftStack = new Stack<Node>();
                Stack<Node> rightStack = new Stack<Node>();
                do {
                    while (tempNode != null) {
                        rightChild = tempNode.rightChild;
                        leftStack.push(tempNode);
                        rightStack.push(rightChild);
                        tempNode = tempNode.leftChild;
                    }
                    tempNode = leftStack.pop();
                    rightChild = rightStack.pop();
                    if (rightChild == null) {
                        for (int i = tempNode.equivalent; i >= 0; i --) {
                            resultArray[index ++] = tempNode.data;
                        }
                    } else {
                        leftStack.push(tempNode);
                        rightStack.push(null);
                    }
                    tempNode = rightChild;
                } while (!leftStack.isEmpty() || !rightStack.isEmpty());
            }
            
            return resultArray;
        }
        
        public int[] postorderTraversalC() {
            int[] resultArray = new int[size];
            if (size > 0) {
                int index = 0;
                Node tempNode = root;
                Stack<Node> stackA = new Stack<Node>();
                Stack<Node> stackB = new Stack<Node>();
                while (tempNode != null || !stackA.isEmpty()) {
                    while (tempNode != null) {
                        stackA.push(tempNode);
                        stackB.push(tempNode);
                        tempNode = tempNode.rightChild;
                    }
                    if (!stackA.isEmpty()) {
                        tempNode = stackA.pop();
                        tempNode = tempNode.leftChild;
                    }
                }
                while (!stackB.isEmpty()) {
                    tempNode = stackB.pop();
                    for (int i = tempNode.equivalent; i >= 0; i --) {
                        resultArray[index ++] = tempNode.data;
                    }
                }
            }
            
            return resultArray;
        }
        
        /*
         * The tree's level order traversal.
         */
        public int[] levelOrderTraversal() {
            
            int[] resultArray = new int[size];
            
            if (size > 0) {
                int index = 0;
                Node tempNode = root;
                Queue<Node> alternationQueueA = new LinkedList<Node>();
                Queue<Node> alternationQueueB = new LinkedList<Node>();
                while (tempNode != null || !alternationQueueA.isEmpty()
                        || !alternationQueueB.isEmpty()) {
                    
                    if (tempNode != null) {
                        for (int i = tempNode.equivalent; i >= 0; i --) {
                            resultArray[index ++] = tempNode.data;
                        }
                        if (tempNode.leftChild != null) {
                            alternationQueueA.offer(tempNode.leftChild);
                        }
                        if (tempNode.rightChild != null) {
                            alternationQueueA.offer(tempNode.rightChild);
                        }
                        tempNode = null;
                    } else {
                        Node queueNode = null;
                        while (!alternationQueueA.isEmpty()) {
                            queueNode = alternationQueueA.poll();
                            if (queueNode.leftChild != null) {
                                alternationQueueB.offer(queueNode.leftChild);
                            }
                            if (queueNode.rightChild != null) {
                                alternationQueueB.offer(queueNode.rightChild);
                            }
                            for (int i = queueNode.equivalent; i >= 0; i --) {
                                resultArray[index ++] = queueNode.data;
                            }
                        }
                        while (!alternationQueueB.isEmpty()) {
                            queueNode = alternationQueueB.poll();
                            if (queueNode.leftChild != null) {
                                alternationQueueA.offer(queueNode.leftChild);
                            }
                            if (queueNode.rightChild != null) {
                                alternationQueueA.offer(queueNode.rightChild);
                            }
                            for (int i = queueNode.equivalent; i >= 0; i --) {
                                resultArray[index ++] = queueNode.data;
                            }
                        }
                    }
                }
            }
            
            return resultArray;
        }
        
        public int[] anotherLevelOrderTraversal() {
            int[] resultArray = new int[size];
            if (size > 0) {
                int index = 0;
                Node tempNode = root;
                Queue<Node> assistanceQueue = new LinkedList<Node>();
                assistanceQueue.offer(tempNode);
                while (!assistanceQueue.isEmpty()) {
                    tempNode = assistanceQueue.poll();
                    for (int i = tempNode.equivalent; i >= 0; i --) {
                        resultArray[index ++] = tempNode.data;
                    }
                    if (tempNode.leftChild != null) {
                        assistanceQueue.offer(tempNode.leftChild);
                    }
                    if (tempNode.rightChild != null) {
                        assistanceQueue.offer(tempNode.rightChild);
                    }
                }
            }
            
            return resultArray;
        }
    
    }

  • PS:
    • Code还是去年工作半年闲暇时码的,目的是为了弥补自己本科期间没有动手写这些基础code的缺憾
    • 总是工作时抽闲写一点,注释较少,望君手下留情
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值