/** {@inheritDoc} */
  @Override
  protected boolean validateNode(Node<T> node) {
    boolean bst = super.validateNode(node);
    if (!bst) return false;

    AVLNode<T> avlNode = (AVLNode<T>) node;
    int balanceFactor = avlNode.getBalanceFactor();
    if (balanceFactor > 1 || balanceFactor < -1) {
      return false;
    }
    if (avlNode.isLeaf()) {
      if (avlNode.height != 1) return false;
    } else {
      AVLNode<T> avlNodeLesser = (AVLNode<T>) avlNode.lesser;
      int lesserHeight = 1;
      if (avlNodeLesser != null) lesserHeight = avlNodeLesser.height;

      AVLNode<T> avlNodeGreater = (AVLNode<T>) avlNode.greater;
      int greaterHeight = 1;
      if (avlNodeGreater != null) greaterHeight = avlNodeGreater.height;

      if (avlNode.height == (lesserHeight + 1) || avlNode.height == (greaterHeight + 1))
        return true;
      return false;
    }

    return true;
  }
Example #2
0
  static AVLNode rebalancing(AVLNode root) {
    root.ht = Math.max(height(root.left), height(root.right)) + 1;

    int bf = height(root.left) - height(root.right);

    if (bf > 1) {

      bf = height(root.left.left) - height(root.left.right);
      if (bf < 0) {
        root.left = rotate(root.left, true);
      }

      root = rotate(root, false);
    } else if (bf < -1) {

      bf = height(root.right.left) - height(root.right.right);
      if (bf > 0) {
        root.right = rotate(root.right, false);
      }

      root = rotate(root, true);
    }

    return root;
  }
  /** {@inheritDoc} */
  @Override
  protected Node<T> removeValue(T value) {
    // Find node to remove
    Node<T> nodeToRemoved = this.getNode(value);
    if (nodeToRemoved == null) return null;

    // Find the replacement node
    Node<T> replacementNode = this.getReplacementNode(nodeToRemoved);

    // Find the parent of the replacement node to re-factor the height/balance of the tree
    AVLNode<T> nodeToRefactor = null;
    if (replacementNode != null) nodeToRefactor = (AVLNode<T>) replacementNode.parent;
    if (nodeToRefactor == null) nodeToRefactor = (AVLNode<T>) nodeToRemoved.parent;
    if (nodeToRefactor != null && nodeToRefactor == nodeToRemoved)
      nodeToRefactor = (AVLNode<T>) replacementNode;

    // Replace the node
    replaceNodeWithNode(nodeToRemoved, replacementNode);

    // Re-balance the tree all the way up the tree
    while (nodeToRefactor != null) {
      nodeToRefactor.updateHeight();
      balanceAfterDelete(nodeToRefactor);

      nodeToRefactor = (AVLNode<T>) nodeToRefactor.parent;
    }

    return nodeToRemoved;
  }
Example #4
0
  protected AVLNode<T> insert(T data, AVLNode<T> t) throws Exception {
    if (t == null) t = new AVLNode<T>(data);
    else if (data.compareTo(t.data) < 0) {
      t.left = insert(data, t.left);

      if (height(t.left) - height(t.right) == 2) {
        if (data.compareTo(t.left.data) < 0) {
          t = rotateWithLeftChild(t);
          countSingleRotations++;
        } else {
          t = doubleRotateWithleftChild(t);
          countDoubleRotations++;
        }
      }

    } else if (data.compareTo(t.data) > 0) {
      t.right = insert(data, t.right);

      if (height(t.right) - height(t.left) == 2) {
        if (data.compareTo(t.right.data) > 0) {
          t = rotateWithRightChild(t);
          countSingleRotations++;
        } else {
          t = doubleRotateWithRightChild(t);
          countDoubleRotations++;
        }
      }

    } else {
      throw new Exception("Attempting to insert to duplicate value");
    }

    t.height = max(height(t.left), height(t.right)) + 1;
    return t;
  }
Example #5
0
  protected AVLNode<T> rotateWithRightChild(AVLNode<T> root) {
    AVLNode<T> newRoot = root.right;
    root.right = newRoot.left;
    newRoot.left = root;

    root.height = max(height(root.left), height(root.right)) + 1;
    newRoot.height = max(height(newRoot.right), root.height) + 1;
    return newRoot;
  }
Example #6
0
 /*
  * Returns the parent tree
  */
 public AVLNode<E> get_parent_helper(AVLNode<E> currentNode, AVLNode<E> root, AVLNode<E> x) {
   if (currentNode == null) return null;
   // System.out.println("current " + currentNode.getElement() + " and x " + x.getElement() );
   // System.out.println(".equls is " + currentNode.getElement().equals(x.getElement()));
   if (currentNode.getElement().equals(x.getElement())) {
     return root;
   }
   AVLNode<E> value = get_parent_helper(currentNode.getLeft(), currentNode, x);
   if (value == null) return get_parent_helper(currentNode.getRight(), currentNode, x);
   return value;
 }
Example #7
0
  public AVLNode<T> remove(T x, AVLNode<T> t) {
    if (t == null) {
      System.out.println("Sorry but you're mistaken, " + t + " doesn't exist in this tree :)\n");
      return null;
    }
    System.out.println("Remove starts... " + t.data + " and " + x);

    if (x.compareTo(t.data) < 0) {
      t.left = remove(x, t.left);
      int le = t.left != null ? t.left.height : 0;

      if ((t.right != null) && (t.right.height - le >= 2)) {
        int rightHeight = t.right.right != null ? t.right.right.height : 0;
        int leftHeight = t.right.left != null ? t.right.left.height : 0;
        if (rightHeight >= leftHeight) t = rotateWithLeftChild(t);
        else t = doubleRotateWithRightChild(t);
      }

    } else if (x.compareTo(t.data) > 0) {
      t.right = remove(x, t.right);
      int ri = t.right != null ? t.right.height : 0;
      if ((t.left != null) && (t.left.height - ri >= 2)) {
        int leftHeight = t.left.left != null ? t.left.left.height : 0;
        int rightHeight = t.left.right != null ? t.left.right.height : 0;
        if (leftHeight >= rightHeight) t = rotateWithRightChild(t);
        else t = doubleRotateWithleftChild(t);
      }

    } else if (t.left != null) {
      t.data = findMax(t.left).data;
      remove(t.data, t.left);

      if ((t.right != null) && (t.right.height - t.left.height >= 2)) {
        int rightHeight = t.right.right != null ? t.right.right.height : 0;
        int leftHeight = t.right.left != null ? t.right.left.height : 0;
        if (rightHeight >= leftHeight) t = rotateWithLeftChild(t);
        else t = doubleRotateWithRightChild(t);
      }

    } else {
      t = (t.left != null) ? t.left : t.right;
    }

    if (t != null) {
      int leftHeight = (t.left != null) ? t.left.height : 0;
      int rightHeight = (t.right != null) ? t.right.height : 0;
      t.height = max(leftHeight, rightHeight) + 1;
    }

    return t;
  }
Example #8
0
  /**
   * Update the path from node down to the node containing element. Since it is guaranteed there is
   * a path between these two arguments, node should never become null.
   *
   * @param node the root of some subtree, originally the root of the subtree whose node was
   *     removed.
   * @param element the element stored at the end of the path to be updated. This element was the
   *     parent to the value t hat supplied the replacement value for a node during a remove()
   *     operation.
   */
  private AVLNode<E> updatePath(AVLNode<E> node, E element) {
    int compareResult = element.compareTo(node.getElement());

    if (compareResult == 0) { // reached the end of the path
      node = fixSubtreeRootedAt(node);
    } else if (compareResult < 0) {
      node.leftChild = updatePath((AVLNode<E>) node.leftChild, element);
      node = fixSubtreeRootedAt(node);
    } else if (compareResult > 0) {
      node.rightChild = updatePath((AVLNode<E>) node.rightChild, element);
      node = fixSubtreeRootedAt(node);
    }
    return node;
  }
Example #9
0
  // https://www.hackerrank.com/challenges/self-balancing-tree
  public AVLNode insert(AVLNode root, int val) {
    if (root == null) {
      AVLNode node = new AVLNode();
      node.val = val;
      node.ht = 0;
      return node;
    }
    if (root.val > val) {
      root.left = insert(root.left, val);

    } else {
      root.right = insert(root.right, val);
    }
    return rebalancing(root);
  }
Example #10
0
  /**
   * Perform a right (clockwise) rotation at <tt>x</tt>.
   *
   * @param x the lowest unbalanced node found in this tree.
   * @return The new root of the balanced subtree.
   */
  private AVLNode<E> rightRotation(AVLNode<E> x) {
    AVLNode<E> newRoot = (AVLNode<E>) x.leftChild;
    newRoot.parent = x.parent;
    x.parent = newRoot;
    x.leftChild = newRoot.rightChild;
    // newRoot is guaranteed to have a left child, but
    //  we can't be sure it has a right child
    if (newRoot.rightChild != null) {
      newRoot.rightChild.parent = x;
    }
    newRoot.rightChild = x;

    // lastly: do updates from the bottom up
    updateBalanceAndHeight(x);
    updateBalanceAndHeight(newRoot);
    return newRoot;
  }
Example #11
0
  public static void rotateRight(AVLNode origRoot) {

    // === Difference from rotateLeft ===
    AVLNode newRoot = origRoot.left;
    // Original root's left (previously new root) becomes new root's right
    origRoot.left = newRoot.right;
    // New root's right becomes original root
    newRoot.right = origRoot;

    // If original root is not root of tree
    if (origRoot.parent != null) {
      // Update new root's parent's link to it based on
      // whether original root is left or right child
      if (origRoot.parent.left.key == origRoot.key) {
        origRoot.parent.left = newRoot;
      } else {
        origRoot.parent.right = newRoot;
      }
    }
    // Update new root's parent to be original root's parent
    newRoot.parent = origRoot.parent;
    // Update original root's parent to be new root
    origRoot.parent = newRoot;

    // Update heights of original and new root
    newRoot.height -= 1;
    origRoot.height += 1;
  }
Example #12
0
 static AVLNode rotate(AVLNode root, boolean isLeft) {
   if (isLeft) {
     AVLNode right = root.right;
     root.right = right.left;
     right.left = root;
     root.ht = Math.max(height(root.left), height(root.right)) + 1;
     root = right;
     root.ht = Math.max(height(root.left), height(root.right)) + 1;
   } else {
     AVLNode left = root.left;
     root.left = left.right;
     left.right = root;
     root.ht = Math.max(height(root.left), height(root.right)) + 1;
     root = left;
     root.ht = Math.max(height(root.left), height(root.right)) + 1;
   }
   return root;
 }
Example #13
0
 private AVLNode rotate(AVLNode T) {
   if (T == null) return null;
   if (Height(T.getLeft()) - Height(T.getRight()) == 2) {
     if (Height(T.getLeft().getLeft()) >= Height(T.getLeft().getRight()))
       return SingleRotateWithLeft(T);
     else return DoubleRotateWithLeft(T);
   } else if (Height(T.getRight()) - Height(T.getLeft()) == 2) {
     if (Height(T.getRight().getRight()) >= Height(T.getRight().getLeft()))
       return SingleRotateWithRight(T);
     else return DoubleRotateWithRight(T);
   }
   return T;
 }
Example #14
0
  @Override
  protected void balance(AVLNode<T> node) {
    /* Rotation cases (N = node, C = child)
     * Case 1:
     *     N
     *    /
     *   C
     *  /
     * O
     *
     * Case 2:
     *   N
     *  /
     * C
     *  \
     *   O
     *
     * Case 3:
     * N
     *  \
     *   C
     *    \
     *     O
     * Case 4:
     * N
     *  \
     *   C
     *  /
     * O
     */

    if (node == null) return;
    int bf = node.getBalanceFactor();

    if (bf == 2) {
      AVLNode<T> child = node.getLeftChild();

      if (child.getBalanceFactor() == -1) // Case 2
      rotateLeft(child);

      rotateRight(node); // Case 1
    } else if (bf == -2) {
      AVLNode<T> child = node.getRightChild();

      if (child.getBalanceFactor() == 1) // Case 4
      rotateRight(child);

      rotateLeft(node); // Case 3
    } else balance(node.getParent()); // Recurrsively balance parent
  }
  /** {@inheritDoc} */
  @Override
  protected Node<T> addValue(T id) {
    Node<T> nodeToReturn = super.addValue(id);
    AVLNode<T> nodeAdded = (AVLNode<T>) nodeToReturn;
    nodeAdded.updateHeight();
    balanceAfterInsert(nodeAdded);

    nodeAdded = (AVLNode<T>) nodeAdded.parent;
    while (nodeAdded != null) {
      int h1 = nodeAdded.height;

      nodeAdded.updateHeight();
      balanceAfterInsert(nodeAdded);

      // If height before and after balance is the same, stop going up the tree
      int h2 = nodeAdded.height;
      if (h1 == h2) break;

      nodeAdded = (AVLNode<T>) nodeAdded.parent;
    }
    return nodeToReturn;
  }
Example #16
0
 /*
  * Return the parent tree
  */
 public AVLNode<E> get_parent(AVLNode<E> x) {
   if (rootAbove.getLeft() == null) {
     return null;
   } else if (x == null) {
     return null;
   } else if (rootAbove.getLeft().getElement().equals(x.getElement())) {
     return null;
   }
   AVLNode<E> value = get_parent_helper(rootAbove.getLeft(), rootAbove.getLeft(), x);
   if (value == null) return get_parent_helper(rootAbove.getRight(), rootAbove.getLeft(), x);
   return value;
 }
Example #17
0
  /**
   * On entry, <tt>x</tt> is the root of a subtree that has violated the balance properties of an
   * AVL tree, so requires rebalancing.
   *
   * @param x the root of the tree to be rebalanced.
   * @return The new root of the balanced subtree.
   */
  private AVLNode<E> rebalance(AVLNode<E> x) {
    AVLNode<E> newRoot = null; // new root of  balanced subtree

    // LL case - new node inserted into left subtree of
    //       last unbalanced node's left child
    if (x.balance == 2) { // left subtree is unbalanced
      // Check for LL CASE
      if (((AVLNode<E>) x.leftChild).balance == 1) {
        newRoot = rightRotation(x);
      } else { // LR CASE
        x.leftChild = leftRotation((AVLNode<E>) x.leftChild);
        newRoot = rightRotation(x);
      }
    } else if (x.balance == -2) { // right subtree is unbalanced
      // Check for RR CASE
      if (((AVLNode<E>) x.rightChild).balance == -1) {
        newRoot = leftRotation(x);
      } else { // LR case
        x.rightChild = rightRotation((AVLNode<E>) x.rightChild);
        newRoot = leftRotation(x);
      }
    }
    return newRoot;
  }
Example #18
0
  /**
   * @param element: The element to remove from the AVLTree
   * @param temp: The root node of the subtree
   *     <p>This method recursively traverses the AVLTree based on the ordering of the element with
   *     respect to the Tree's elements. If the element is not found, then nothing happens.
   *     Otherwise, the element is removed, and either the far-right element on its left child or
   *     the far left element on its right child replaces it. *
   */
  private void remove(E element, AVLNode<E> temp) {
    if (temp == null) return;

    int compare = 0;

    if (temp != rootAbove) compare = element.compareTo(temp.getElement());

    boolean direction = (compare > 0 && temp != rootAbove);

    AVLNode<E> child = direction ? temp.getRight() : temp.getLeft();

    if (child == null) return;

    // if the root is perfectly balanced, slide the left Node up
    // and reinsert the left.right element if necessary
    if (temp == rootAbove && child.getBalance() == 0 && child.getElement().equals(element)) {

      AVLNode<E> newRoot = child.getLeft();

      if (newRoot == null) {
        rootAbove.setLeftNode(null);
        return;
      } else {
        enactRemoval(temp, child, false);
        return;
      }
    }

    // if the element is found and the root is not
    // perfectly balanced, remove it using enactRemoval()
    else if (element.compareTo(child.getElement()) == 0) {
      enactRemoval(temp, child, direction);
    }

    // otherwise, recursively traverse the tree
    else {
      remove(element, child);
    }
  }
Example #19
0
  /**
   * @param element: The element to search for in the AVLTree
   * @return boolean: true if the element is found, false otherwise
   *     <p>The contains method simply traverses the binary search tree based on element's relation
   *     to the AVLNodes in the Tree until a match is found or it hits the bottom of the Tree.
   */
  public boolean contains(E element) {

    AVLNode<E> temp = rootAbove.getLeft();

    while (temp != null) {
      if (temp.getElement().equals(element)) return true;

      int balance = element.compareTo(temp.getElement());
      temp = (balance < 0) ? temp.getLeft() : temp.getRight();
    }

    return false;
  }
Example #20
0
  public AVLNode<E> find(E element) {

    AVLNode<E> temp = rootAbove.getLeft();

    while (temp != null) {
      if (temp.getElement().equals(element)) return temp;

      int balance = element.compareTo(temp.getElement());
      temp = (balance < 0) ? temp.getLeft() : temp.getRight();
    }

    return null;
  }
Example #21
0
 private void addChildTree(DefaultMutableTreeNode root, AVLNode avlRoot) {
   if (avlRoot.getLeft() != null) {
     DefaultMutableTreeNode leftNode =
         new DefaultMutableTreeNode(new AVLTreeNode(avlRoot.getLeft(), "Left  "));
     addChildTree(leftNode, avlRoot.getLeft());
     root.add(leftNode);
   }
   if (avlRoot.getRight() != null) {
     DefaultMutableTreeNode rightNode =
         new DefaultMutableTreeNode(new AVLTreeNode(avlRoot.getRight(), "Right "));
     addChildTree(rightNode, avlRoot.getRight());
     root.add(rightNode);
   }
 }
  /**
   * Balance the tree according to the AVL post-delete algorithm.
   *
   * @param node Root of tree to balance.
   */
  private void balanceAfterDelete(AVLNode<T> node) {
    int balanceFactor = node.getBalanceFactor();
    if (balanceFactor == -2 || balanceFactor == 2) {
      if (balanceFactor == -2) {
        AVLNode<T> ll = (AVLNode<T>) node.lesser.lesser;
        int lesser = (ll != null) ? ll.height : 0;
        AVLNode<T> lr = (AVLNode<T>) node.lesser.greater;
        int greater = (lr != null) ? lr.height : 0;
        if (lesser >= greater) {
          rotateRight(node);
          node.updateHeight();
          if (node.parent != null) ((AVLNode<T>) node.parent).updateHeight();
        } else {
          rotateLeft(node.lesser);
          rotateRight(node);

          AVLNode<T> p = (AVLNode<T>) node.parent;
          if (p.lesser != null) ((AVLNode<T>) p.lesser).updateHeight();
          if (p.greater != null) ((AVLNode<T>) p.greater).updateHeight();
          p.updateHeight();
        }
      } else if (balanceFactor == 2) {
        AVLNode<T> rr = (AVLNode<T>) node.greater.greater;
        int greater = (rr != null) ? rr.height : 0;
        AVLNode<T> rl = (AVLNode<T>) node.greater.lesser;
        int lesser = (rl != null) ? rl.height : 0;
        if (greater >= lesser) {
          rotateLeft(node);
          node.updateHeight();
          if (node.parent != null) ((AVLNode<T>) node.parent).updateHeight();
        } else {
          rotateRight(node.greater);
          rotateLeft(node);

          AVLNode<T> p = (AVLNode<T>) node.parent;
          if (p.lesser != null) ((AVLNode<T>) p.lesser).updateHeight();
          if (p.greater != null) ((AVLNode<T>) p.greater).updateHeight();
          p.updateHeight();
        }
      }
    }
  }
Example #23
0
  public AVLNode<E> get_left_neighbor(AVLNode<E> x) {
    AVLNode<E> left_child = x.getLeft();
    AVLNode<E> ret = left_child;
    if (left_child == null) {
      if (get_parent(x) != null && get_parent(x).getElement().compareTo(x.getElement()) == -1) {
        return get_parent(x);
      } else {
        return null;
      }
    }
    AVLNode<E> right = left_child.getRight();

    while (right != null) {
      ret = right;
      right = right.getRight();
    }

    return ret;
  }
  /**
   * Balance the tree according to the AVL post-insert algorithm.
   *
   * @param node Root of tree to balance.
   */
  private void balanceAfterInsert(AVLNode<T> node) {
    int balanceFactor = node.getBalanceFactor();
    if (balanceFactor > 1 || balanceFactor < -1) {
      AVLNode<T> child = null;
      Balance balance = null;
      if (balanceFactor < 0) {
        child = (AVLNode<T>) node.lesser;
        balanceFactor = child.getBalanceFactor();
        if (balanceFactor < 0) balance = Balance.LEFT_LEFT;
        else balance = Balance.LEFT_RIGHT;
      } else {
        child = (AVLNode<T>) node.greater;
        balanceFactor = child.getBalanceFactor();
        if (balanceFactor < 0) balance = Balance.RIGHT_LEFT;
        else balance = Balance.RIGHT_RIGHT;
      }

      if (balance == Balance.LEFT_RIGHT) {
        // Left-Right (Left rotation, right rotation)
        rotateLeft(child);
        rotateRight(node);
      } else if (balance == Balance.RIGHT_LEFT) {
        // Right-Left (Right rotation, left rotation)
        rotateRight(child);
        rotateLeft(node);
      } else if (balance == Balance.LEFT_LEFT) {
        // Left-Left (Right rotation)
        rotateRight(node);
      } else {
        // Right-Right (Left rotation)
        rotateLeft(node);
      }

      child.updateHeight();
      node.updateHeight();
    }
  }
Example #25
0
 @Override
 protected void rotateRight(AVLNode<T> node) {
   super.rotateRight(node);
   node.resetHeights(); // Reset Height after rotation
 }
Example #26
0
 /** Update the balance and height properties of <tt>node</tt>. */
 private void updateBalanceAndHeight(AVLNode<E> node) {
   int leftHeight = height((AVLNode<E>) node.leftChild);
   int rightHeight = height((AVLNode<E>) node.rightChild);
   node.height = (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
   node.balance = leftHeight - rightHeight;
 }
Example #27
0
 @Override
 public String toString() {
   return title + String.valueOf(node.getValue()) + "|" + node.getHeight();
 }
Example #28
0
  AVLNode insert(int x, AVLNode T) {
    if (T == null) {
      T = new AVLNode();
      T.setValue(x);
      T.setLeft(null);
      T.setRight(null);
    } else if (x < T.getValue()) {
      T.setLeft(insert(x, T.getLeft()));
      if (Height(T.getLeft()) - Height(T.getRight()) == 2) {
        if (x < T.getLeft().getValue()) T = SingleRotateWithLeft(T);
        else T = DoubleRotateWithLeft(T);
      }
    } else if (x > T.getValue()) {
      T.setRight(insert(x, T.getRight()));
      if (Height(T.getRight()) - Height(T.getLeft()) == 2)
        if (x > T.getRight().getValue()) T = SingleRotateWithRight(T);
        else T = DoubleRotateWithRight(T);
    }

    T.setHeight(Math.max(Height(T.getLeft()), Height(T.getRight())) + 1);
    return T;
  }
Example #29
0
 int Height(AVLNode avl) {
   if (avl == null) return -1;
   else return avl.getHeight();
 }
Example #30
0
 AVLNode findMin(AVLNode tree) {
   if (tree != null) while (tree.getLeft() != null) tree = tree.getLeft();
   return tree;
 }