Exemplo n.º 1
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 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;
  }
  /**
   * 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();
    }
  }
  /**
   * 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();
        }
      }
    }
  }