/** * Iteratively traverses a tree from the specified node in a post-order fashion, performing * computations at each node. * * @param node The node the traversal starts from. * @param pv The population vector to use for node computations. */ public void iterativeTraverse(Node root, PopulationVector pv) { Stack<Node> s = new Stack<Node>(); s.push(root); Node prev = null; while (!s.empty()) { Node curr = s.peek(); if (prev == null || prev.leftChild() == curr || prev.rightChild() == curr) { if (curr.leftChild() != null) s.push(curr.leftChild()); else if (curr.rightChild() != null) s.push(curr.rightChild()); // If traversing up tree from left, traverse to right child if available. } else if (curr.leftChild() == prev && curr.rightChild() != null) { s.push(curr.rightChild()); } // Otherwise traversing up tree from right, compute g arrays and pop. else { if (curr.isLeaf()) { initLeafNode(curr, pv); } else { computeSubnetNode(curr, pv); } s.pop(); } prev = curr; } }
/** * Recurse down the binary tree and delete the specified node * * @param node Start Node * @param data Node to be deleted * @return */ public Node delete(Node node, int data) { /** * A Node can be one of the following types: 1. Leaf Node 2. With one child 3. With two child */ if (data < node.data) { node.leftChild = delete(node.leftChild, data); } else if (data > node.data) { node.rightChild = delete(node.rightChild, data); } else { /** Leaf Node */ if (node.rightChild == null && node.leftChild == null) node = null; /** Node with one child */ else if (node.leftChild == null) node = node.rightChild; else if (node.rightChild == null) node = node.rightChild; else { /** * Node with 2 child. Replace the node with any of its sibling and then delete the sibling */ node.data = node.leftChild.data; node.leftChild = null; } } return node; }
/** * Helper-function: For the given node, recursively insert a duplicate node on each node's left * * @param node input node */ public void doubleTree(Node node) { if (node == null) return; doubleTree(node.leftChild); doubleTree(node.rightChild); Node newnode = new Node(node.data); newnode.leftChild = node.leftChild; node.leftChild = newnode; }
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; }
/** * Recursively traverses a tree from the specified node in a post-order fashion, performing * computations at each node. * * @param node The node the traversal starts from. * @param pv The population vector to use for node computations. */ public void recursiveTraverse(Node node, PopulationVector pv) { if (node.leftChild() != null) { recursiveTraverse(node.leftChild(), pv); } if (node.rightChild() != null) { recursiveTraverse(node.rightChild(), pv); } if (node.isLeaf()) { initLeafNode(node, pv); } else { computeSubnetNode(node, pv); } }
public void insert(int id, double dd) { // found the node like the find method where to insert until this node // has no child , // then insert the insertNode as this node's child Node insertNode = new Node(id, dd); Node current = root; Node parent = null; if (root == null) // no node in tree root = insertNode; else { while (true) { parent = current; if (id <= current.iData) { current = current.leftChild; if (current == null) { parent.leftChild = insertNode; return; } } // end if else { current = current.rightChild; if (current == null) { parent.rightChild = insertNode; return; } } // end else } // end while } // end else }
@Override public boolean add(T obj) { if (root == null) { root = new Node<>(obj); size++; return true; } Node<T> iter = root; while (true) { int compare = obj.compareTo(iter.value); if (compare < 0) { if (iter.leftChild == null) { iter.leftChild = new Node<>(obj, iter); size++; return true; } else { iter = iter.leftChild; } } else if (compare > 0) { if (iter.rightChild == null) { iter.rightChild = new Node<>(obj, iter); size++; return true; } else { iter = iter.rightChild; } } else { return false; } } }
// 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; }
public void insert(String s) { Conversion c = new Conversion(s); s = c.inToPost(); Stack1 stk = new Stack1(s.length()); s = s + "#"; int i = 0; char symbol = s.charAt(i); Node newNode; while (symbol != '#') { if (symbol >= '0' && symbol <= '9' || symbol >= 'A' && symbol <= 'Z' || symbol >= 'a' && symbol <= 'z') { newNode = new Node(symbol); stk.push(newNode); } else if (symbol == '+' || symbol == '-' || symbol == '/' || symbol == '*') { Node ptr1 = stk.pop(); Node ptr2 = stk.pop(); newNode = new Node(symbol); newNode.leftChild = ptr2; newNode.rightChild = ptr1; stk.push(newNode); } symbol = s.charAt(++i); } root = stk.pop(); }
/** * adjoin operation on trees * * @param adj the tree to adjoin in target tree * @return success as true, if adjoin was successfull */ public boolean adjoin(Node adj) { boolean success = false; if (adj.parent == null) { // check that adj is the root node Node adjFoot = adj.getNode(adj.data, true); // find foot node of adjoining tree if (adjFoot.getData().equals(adj.getData())) { // check that adj is an possible adjoining tree Node partialTreeRoot = this.getNode( adj.getData(), false); // save partial tree which gets separated through adjoin if (partialTreeRoot.data.equals( adj.getData())) { // check that there is an appropriate node in tree Node mainTreeLeaf = partialTreeRoot.parent; // save leaf of main tree on which to adjoin adjFoot.leftChild = partialTreeRoot.leftChild; // parse partial tree to foot of adjoining tree adjFoot.rightChild = partialTreeRoot.rightChild; adjFoot.foot = false; // remove the foot tag if (mainTreeLeaf.leftChild.data.equals( adj.data)) { // find out if tree has to be adjoined on left child mainTreeLeaf.leftChild = adj; } else if (mainTreeLeaf.rightChild.data.equals(adj.data)) { // or right child mainTreeLeaf.rightChild = adj; } success = true; } } } else { // if it wasn't the root success = this.adjoin(adj.parent); // search for it recursively } return success; }
/** * Helper-function: For the given node, recurse through it and swap left tree with right subtree * * @param node */ public void mirror(Node node) { // Terminating case if (node == null) mirror(node.leftChild); mirror(node.rightChild); Node temp = node.leftChild; node.leftChild = node.rightChild; node.rightChild = temp; }
/** * Given a node pointer, recurse down and insert the new node at the correct location * * @param node Given node pointer * @param data New data to be added * @return New node that is added */ public Node insert(Node node, int data) { if (node == null) { node = new Node(data); } else if (data < node.data) { node.leftChild = insert(node.leftChild, data); } else node.rightChild = insert(node.rightChild, data); return node; }
public static void main(String[] args) { Node root = new Node(100); Node n1 = new Node(50); Node n2 = new Node(25); Node n3 = new Node(75); Node n4 = new Node(150); Node n5 = new Node(125); Node n6 = new Node(110); Node n7 = new Node(175); root.leftChild = n1; root.rightChild = n4; n1.leftChild = n2; n1.rightChild = n3; n4.leftChild = n5; n4.rightChild = n7; n5.leftChild = n6; preorder(root); }
public void insert(int data) { System.out.println("Inserting " + data + " to the BST."); // deal with empty tree case if (root == null) { System.out.println("The new node becomes the root."); root = new Node(data); } // look for proper location to put the new node else { Node current = root; Node previous = root; // used to store current's parent boolean isLeft = false; while (true) { // System.out.println("current is "+current.iData); if (data < current.iData) { // go to left child System.out.println("Making a left."); isLeft = true; if (current.leftChild != null) { previous = current; current = current.leftChild; } else { break; } } else { System.out.println("Making a right."); isLeft = false; if (current.rightChild != null) { current = current.rightChild; } else { break; } } previous = current; // save parent node before entering next iteration } current = new Node(data); if (isLeft) { previous.leftChild = current; } else { previous.rightChild = current; } } System.out.println(""); // display an empty line }
/** * find the successor which is the smallest of the set of nodes that are larger than the deleted * node the algorithm of finding the successor: First, the program goes to the original node’s * right child, which must have a key larger than the node. Then it goes to this right child’s * left child (if it has one), and to this left child’s left child, and so on, following down the * path of left children. The last left child in this path is the successor of the original node, * as shown in Figure specialized situation: successor is the delete node's right child, so * successor has no left child * * @param delNode the deleted node * @return the successor node which has made connection already */ private Node getSuccessor(Node delNode) { Node successorParent = delNode; Node successor = delNode; Node current = delNode.rightChild; // go to right node while (current != null) { successorParent = successor; successor = current; current = current.leftChild; // go to left node } // end while // if successor not the delete node's right child, making connections if (successor != delNode.rightChild) { successorParent.leftChild = successor.rightChild; successor.rightChild = delNode.rightChild; } // end if return successor; }
/** * ********************************* 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 getSuccessor(Node delNode) { // Node current; Node previous; System.out.println("Starting get the successor of the node [" + delNode.iData + "]."); if (delNode.rightChild == null) { System.out.println("The node to be removed does not have a successor."); System.out.println("This method is very likely called wrongly by 'remove' method."); return null; } else { current = delNode.rightChild; // go right first previous = delNode.rightChild; // go to successor node while (true) { if (current.leftChild != null) { System.out.println("Make a left."); previous = current; // keep track of current's parent, this MUST be done!! current = current.leftChild; } else { break; } } // special case: successor is or isn't delnode's rightChild if (current != delNode.rightChild) { // successor's parent no longer has a left child previous.leftChild = null; // successor's right child points to del node's right child current.rightChild = delNode.rightChild; } System.out.println("The successor of the target node is " + current.iData); return current; } }
public void addNode(int key, String name) { // Create a new Node and initialize it Node newNode = new Node(key, name); // If there is no root this becomes root if (this.root == null) { this.root = newNode; } else { // Set root as the Node we will start // with as we traverse the tree Node focusNode = this.root; // Future parent for our new Node Node parent; while (true) { // root is the top parent so we start // there parent = focusNode; // Check if the new node should go on // the left side of the parent node if (key < focusNode.key) { // Switch focus to the left child focusNode = focusNode.leftChild; // If the left child has no children if (focusNode == null) { // then place the new node on the left of it parent.leftChild = newNode; return; // All Done } } else { // If we get here put the node on the right focusNode = focusNode.rightChild; // If the right child has no children if (focusNode == null) { // then place the new node on the right of it parent.rightChild = newNode; return; // All Done } } } } }
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; }
/** * finding the node you want to delete then considering three cases: 1. The node to be deleted is * a leaf (has no children). 2. The node to be deleted has one child. 3. The node to be deleted * has two children. * * @param key delete node with given key * @return if the key exit and deletes it, return true, otherwise return false */ public boolean delete(int key) { Node current = root; // record the delete node Node parent = root; // parent of current node boolean isLeftChild = true; // if current is parent's left // child,isLeftChild equals true, otherwise // false // find the node with key while (current.iData != key) { parent = current; if (key < current.iData) { isLeftChild = true; current = current.leftChild; } // end if else { isLeftChild = false; current = current.rightChild; } // end else if (current == null) return false; // didn't find } // end while // found node to delete // ---case 1: The node to be deleted is a leaf (has no children). // specialized situation: the delete node is the root if (current.leftChild == null && current.rightChild == null) { if (current == root) // if the found node is root root = null; else if (isLeftChild) parent.leftChild = null; else parent.rightChild = null; } // end if // ---case 2: The node to be deleted has one child. // specialized situation: the node to be deleted may be the root, in // which case it has no parent and is simply replaced by the appropriate // subtree. else if (current.rightChild == null) // if no right child,replace with // left subtree { if (current == root) root = current.leftChild; else if (isLeftChild) parent.leftChild = current.leftChild; else parent.rightChild = current.rightChild; } // end else if else if (current.leftChild == null) // if no left chuld { if (current == root) root = current.rightChild; else if (isLeftChild) parent.leftChild = current.leftChild; else parent.rightChild = current.rightChild; } // end else if // ---base case3: The node to be deleted has two children. else { // get successor of node to delete(current) Node successor = getSuccessor(current); // connect parent of current to successor instead if (current == root) root = successor; else if (isLeftChild) parent.leftChild = successor; else parent.rightChild = successor; // connect successor to current's left child successor.leftChild = current.leftChild; } // end else return true; }
public boolean remove(int data) { // return 1 when removing finishes Node current = root; Node previous = root; boolean isLeft = false; System.out.println("Trying to remove the node with data " + data); while (true) { if (current == null) { System.out.println("Cannot find the target node, exit."); return false; } else if (current.iData == data) { System.out.print("Found the node to be removed."); if (current == root) { System.out.println("Root is to be removed"); // } else { // type 1: delnode has no child // assign its parent's *Child with null if (current.leftChild == null && current.rightChild == null) { if (isLeft == true) previous.leftChild = null; else previous.rightChild = null; } // type 2: delnode has a single child // connect parent's *Child with delnode's single child else if (current.leftChild == null) { // type 2(a) if (isLeft == true) previous.leftChild = current.rightChild; else previous.rightChild = current.rightChild; } else if (current.rightChild == null) { // type 2(b) if (isLeft == true) previous.leftChild = current.leftChild; else previous.rightChild = current.leftChild; } // type 3: delnode has two children else { // type 3 // assign parent's *child with delnode's successor Node successor = getSuccessor(current); if (isLeft) previous.leftChild = successor; else previous.rightChild = successor; // assign successor's leftChild with delnode's leftChild successor.leftChild = current.leftChild; // assign successor's rightCHild with delnode's rightChild (unless successor is // delnode's rightChild) // assign successor's parent's leftChild with null (unless successor is delnode's // rightChild) // this is done in getSuccessor() } return true; } } else if (data < current.iData) { isLeft = true; previous = current; // save current current = current.leftChild; } else { isLeft = false; previous = current; current = current.rightChild; } } }