AVL Tree

Adelson-Velskii and Landis (AVL) Tree is a #202112121746 with balance condition.

Characteristics

  • The height of left and right subtrees are at most different by 1
  • Maximum height is less than \(1.44 \log (N+2) - 0.328\)

Details

  • Single Rotation and Double Rotation are used to balance the tree

Analysis

  • Always ensure the depth of tree is \(O(\log N)\)
  • All operations, except Insertion, will result in \(O(\log N)\)
  • After single rotation, the tree will return to its original height before insertion

Implementation

#ifdef _AvlTree_H

struct AvlNode;
typdef struct AvlNode *Position;
typdef struct AvlNode *AvlTree;

AvlTree MakeEmpty(AvlTree T);
Position Find(ElementType X, AvlTree T);
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);
AvlTree Insert(ElementType X, AvlTree T);
AvlTree Delete(ElementType X, AvlTree T);
ElementType Retrieve(Position P);

#endif    // _AvlTree_H
struct AvlNode {
  ElementType Element;
  AvlTree     Left;
  AvlTree     Right;
  int         Height;
};

static int Height(Position P) {
  if (P == NULL)
    return -1;
  else
    return P->Height;
}

static int Max(int X, int Y) {
  return X > Y ? X : Y;
}

AvlTree Insert(ElementType X, AvlTree T) {
  if (T == NULL) {
    // Create and return a one-node tree
    T = malloc(sizeof(struct AvlNode));
    if (T == NULL)
      FatalError("Out of space!!!");
    else {
      T->Element = X;
      T->Height = 0;
      T->Left = T->Right = NULL;
    }
  } else if (X < T->Element) {
    T->Left = Insert(X, T->Left);
    if (Height(T->Left) - Height(T->Right) == 2)
      if (X < T->Left->Element)
        T = SingleRotateWithLeft(T);
      else
        T = DoubleRotateWithLeft(T);
  } else if (X > T->Element) {
    T->Right = Insert(X, T->Right);
    if (Height(T->Right) - Height(T->Left) == 2)
      if (X > T->Right->Element)
        T = SingleRotateWithRight(T);
      else
        T = DoubleRotateWithRight(T);
  }

  T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
  return T;
}

/**
 *  This function can be called only if K2 has a left child
 *  Perform a rotate between a node (K2) and its left child
 *  Update heights, then return new root
 */
static Position SingleRotateWithLeft(Position K2) {
  Position K1;

  K1 = K2->Left;
  K2->Left = K1->Right;
  K1->Right = K2;

  K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1;
  K1->Height = Max(Height(K1->Left), K2->Height) + 1;

  return K1;
}

/**
 *  This function can be called only if K3 has a left
 *  child and K3's left child has a right child
 *  Do the left-right double rotation
 *  Update heights, then return new root
 */
static Position DoubleRotateWithLeft(Position K3) {
  // Rotate between K1 and K2
  K3->Left = SingleRotateWithRight(K3->Left);

  // Rotate between K3 and K2
  return SingleRotateWithLeft(K3);
}

/**
 *  This function can be called only if K2 has a right child
 *  Perform a rotate between a node (K2) and its right child
 *  Update heights, then return new root
 */
static Position SingleRotateWithRight(Position K2) {
  Position K1;

  K1 = K2->Right;
  K2->Right = K1->Left;
  K1->Left = K2;

  K2->Height = Max(Height(K2->Right), Height(K2->Left)) + 1;
  K1->Height = Max(Height(K1->Right), K2->Height) + 1;

  return K1;
}

/**
 *  This function can be called only if K3 has a right
 *  child and K3's right child has a left child
 *  Do the right-left double rotation
 *  Update heights, then return new root
 */
static Position DoubleRotateWithRight(Position K3) {
  // Rotate between K1 and K2
  K3->Right = SingleRotateWithLeft(K3->Right);

  // Rotate between K3 and K2
  return SingleRotateWithRight(K3);
}
Links to this page
#data-structure #tree