private Node<T, V> insertTree(Node<T, V> subTree, T t, V v) // called by public void insert(T t) { // insert to a subtree and return the reference of this subtree Node<T, V> ansNode = null; if (subTree == null) { ansNode = new Node<T, V>(t, v); ansNode.leftChild = null; ansNode.rightChild = null; ansNode.height = 0; // null tree's height is -1 } else if (comp.compare(t, subTree.t) < 0) // insert to the leftSubTree of subTree { subTree.leftChild = insertTree(subTree.leftChild, t, v); if (getHeight(subTree.leftChild) - getHeight(subTree.rightChild) == 2) // subtree is the minimum unbalanced subTree { // singleLeftRotate or doubleLeftRightRorate if (getHeight(subTree.leftChild.leftChild) > getHeight(subTree.leftChild.rightChild)) { ansNode = singleLeftRotate(subTree); } else { ansNode = doubleLeftRightRotate(subTree); } } else { // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) >= getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode = subTree; } } else if (comp.compare(t, subTree.t) > 0) // insert to the rightSubTree of subTree { subTree.rightChild = insertTree(subTree.rightChild, t, v); if (getHeight(subTree.rightChild) - getHeight(subTree.leftChild) == 2) // subtree is the minimum unbalanced subTree { // singleLeftRotate or doubleLeftRightRorate if (getHeight(subTree.rightChild.rightChild) > getHeight(subTree.rightChild.leftChild)) { ansNode = singleRightRotate(subTree); } else { ansNode = doubleRightLeftRotate(subTree); } } else { // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) > getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode = subTree; } } return ansNode; }
// create a complete binary tree based on the array Node createCompleteTree(int[] array) { // special cases if (array.length == 0) return null; if (array.length == 1) return new Node(array[0]); LinkedList<Node> Nodes = new LinkedList<>(); Node root = new Node(array[0]); Nodes.add(root); int index = 1; while (!Nodes.isEmpty()) { Node temp = Nodes.pollLast(); // add left child Node newNode = new Node(array[index]); temp.leftChild = newNode; Nodes.addFirst(newNode); index++; // check whether out of range if (index == array.length) break; // add right child newNode = new Node(array[index]); temp.rightChild = newNode; Nodes.addFirst(newNode); index++; // check whether out of range if (index == array.length) break; } return root; }
/** * ********************************* rotation operation * ****************************************************** */ private Node<T, V> singleLeftRotate(Node<T, V> subTree) { // rotate Node<T, V> ansNode = subTree.leftChild; subTree.leftChild = ansNode.rightChild; ansNode.rightChild = subTree; // update height of rotated nodes // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) >= getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode.height = 1 + (getHeight(ansNode.leftChild) >= getHeight(ansNode.rightChild) ? getHeight(ansNode.leftChild) : getHeight(ansNode.rightChild)); return ansNode; }
private Node<T, V> deleteTree(T delT, Node<T, V> subTree) { Node<T, V> ansNode = null; if (subTree == null) { System.err.println(delT + "doesn't exist."); System.err.flush(); ansNode = subTree; } else if (comp.compare(delT, subTree.t) < 0) // delT maybe in the leftSubTree of subTree { subTree.leftChild = deleteTree(delT, subTree.leftChild); // the height of leftSubTree of subTree may decrease // once leftSubTree was return, it is balanced if (getHeight(subTree.rightChild) - getHeight(subTree.leftChild) >= 2) // subtree is the minimum unbalanced subTree { // singleRightRotate or doubleRightLeftRorate if (getHeight(subTree.rightChild.rightChild) >= getHeight(subTree.rightChild.leftChild)) { ansNode = singleRightRotate(subTree); } else { ansNode = doubleRightLeftRotate(subTree); } } else // subTree is balanced, but need to update its height { // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) >= getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode = subTree; } } else if (comp.compare(delT, subTree.t) > 0) // delT maybe in the rightSubTree of subTree { subTree.rightChild = deleteTree( delT, subTree.rightChild); // the height of rightSubTree of subTree may decrease // once rightSubTree was return, it is balanced if (getHeight(subTree.leftChild) - getHeight(subTree.rightChild) >= 2) // subtree is the minimum unbalanced subTree { // singleLeftRotate or doubleLeftRightRotate if (getHeight(subTree.leftChild.leftChild) >= getHeight(subTree.leftChild.rightChild)) { ansNode = singleLeftRotate(subTree); } else { ansNode = doubleLeftRightRotate(subTree); } } else { // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) >= getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode = subTree; } } else if (comp.compare(delT, subTree.t) == 0) { if (subTree.leftChild == null && subTree.rightChild == null) { ansNode = null; // once null is returned, subTree will be recycled anytime } else if (subTree.leftChild != null && subTree.rightChild != null) { subTree.t = getMin(subTree.rightChild).t; subTree.v = getMin(subTree.rightChild).v; subTree.rightChild = deleteTree( subTree.t, subTree.rightChild); // the height of rightSubTree of subTree may decrease // once rightSubTree was return, it is balanced if (getHeight(subTree.leftChild) - getHeight(subTree.rightChild) >= 2) // subtree is the minimum unbalanced subTree { // singleLeftRotate or doubleLeftRightRotate if (getHeight(subTree.leftChild.leftChild) >= getHeight(subTree.leftChild.rightChild)) { ansNode = singleLeftRotate(subTree); } else { ansNode = doubleLeftRightRotate(subTree); } } else { // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) >= getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode = subTree; } } else { if (subTree.leftChild != null && subTree.rightChild == null) { ansNode = subTree.leftChild; // once returned, subTree will be recycled anytime subTree.leftChild = null; } else if (subTree.leftChild == null && subTree.rightChild != null) { ansNode = subTree.rightChild; subTree.rightChild = null; } } } return ansNode; }
private Node<T, V> doubleLeftRightRotate(Node<T, V> subTree) { subTree.leftChild = singleRightRotate(subTree.leftChild); Node<T, V> ansNode = singleLeftRotate(subTree); return ansNode; }