- 二叉排序树还是很容易理解的,无需多讲解,定义:
- 若左子树不空,则左子树上所有结点的值均小于它的根结点的值
- 若右子树不空,则右子树上所有结点的值均大于它的根结点的值
- 左、右子树也分别为二叉排序树
- 代码较多,注释较少,不过还是比较易懂的,但逻辑不一定是最简洁的
- 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的缺憾
- 总是工作时抽闲写一点,注释较少,望君手下留情