Пример #1
0
  /**
   * @param root: The element for which to find a successor AVLNode
   * @return AVLNode<E>: The successor Node *
   */
  private AVLNode<E> findSuccessor(AVLNode<E> root) {
    AVLNode<E> temp = root;
    AVLNode<E> parent = null;

    // if the balance favors the right, traverse right
    // otherwise, traverse left
    boolean direction = (temp.getBalance() > 0);

    parent = temp;
    temp = (direction) ? temp.getRight() : temp.getLeft();

    if (temp == null) return temp;

    // and find the farthest left-Node on the right side,
    // or the farthest right-Node on the left side
    while ((temp.getRight() != null && !direction) || (temp.getLeft() != null && direction)) {

      parent = temp;
      temp = (direction) ? temp.getLeft() : temp.getRight();
    }

    // finally, update the successor's parent's references
    // to adjust for a left child on the right node, or a right
    // child on the left-node
    if (temp == parent.getLeft()) {
      parent.setLeftNode(temp.getRight());
      temp.setRightNode(null);
    } else {
      parent.setRightNode(temp.getLeft());
      temp.setLeftNode(null);
    }

    return temp;
  }
Пример #2
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);
    }
  }
Пример #3
0
  /**
   * @param rotateBase: The root of the subtree that is being rotated
   * @param rootAbove: The AVLNode that points to rotateBase
   *     <p>This method rotates the subtree balancing it to within a margin of |1|.
   */
  public void rotate(AVLNode<E> rotateBase, AVLNode<E> rootAbove) {
    int balance = rotateBase.getBalance();

    if (Math.abs(balance) < 2) {
      // System.out.println("No rotate");
    }

    // gets the child on the side with the greater height
    AVLNode<E> child = (balance < 0) ? rotateBase.getLeft() : rotateBase.getRight();

    if (child == null) return;

    int childBalance = child.getBalance();
    AVLNode<E> grandChild = null;

    // both the child and grandchild are on the
    // left side, so rotate the child up to the root position
    if (balance < -1 && childBalance < 0) {
      if (rootAbove != this.rootAbove && rootAbove.getRight() == rotateBase) {
        rootAbove.setRightNode(child);
      } else {
        rootAbove.setLeftNode(child);
      }

      grandChild = child.getRight();
      child.setRightNode(rotateBase);
      rotateBase.setLeftNode(grandChild);
      return;
    }

    // both the child and the grandchild are on the
    // right side, so rotate the child up to the root position
    else if (balance > 1 && childBalance > 0) {
      if (rootAbove != this.rootAbove && rootAbove.getRight() == rotateBase) {
        rootAbove.setRightNode(child);
      } else {
        rootAbove.setLeftNode(child);
      }

      grandChild = child.getLeft();
      child.setLeftNode(rotateBase);
      rotateBase.setRightNode(grandChild);
      return;
    }

    // the child is on the left side, but the grandchild is on the
    // right side, so rotate the grandchild up to the child position
    // so the condition of the first if statement is satisfied,
    // then recurse to have the first if statement evaluated
    else if (balance < -1 && childBalance > 0) {
      grandChild = child.getRight();
      rotateBase.setLeftNode(grandChild);
      child.setRightNode(grandChild.getLeft());
      grandChild.setLeftNode(child);
      rotate(rotateBase, rootAbove);
      return;
    }

    // the child is on the right side, but the grandchild is on the
    // left side, so rotate the grandchild up to the child position
    // so the condition of the second if statement is satisfied,
    // then recurse to have the second if statement evaluated
    else if (balance > 1 && childBalance < 0) {
      grandChild = child.getLeft();
      rotateBase.setRightNode(grandChild);
      child.setLeftNode(grandChild.getRight());
      grandChild.setRightNode(child);
      rotate(rotateBase, rootAbove);
      return;
    }
  }