AVL Tree C++

AVL Tree is a balanced binary search tree in which any two subtree height only differ by at most 1 i.e height of |Left child – Right child| <= 1. Along with key and value at each node we also store the computed Height property.

We do Rebalancing if…


This content originally appeared on DEV Community and was authored by Lalit Yadav

AVL Tree is a balanced binary search tree in which any two subtree height only differ by at most 1 i.e height of |Left child - Right child| <= 1. Along with key and value at each node we also store the computed Height property.

We do Rebalancing if the difference is more than 1.
AVL supports following operations:-

  • Find in O(logN)
  • Insert in O(logN)
  • Delete in O(logN)

Analysis of operations

 AVLInsert(k, R)
  Insert(k, R)
  N <- Find(k, R)
  Rebalance(N)

 Rebalancing
 if |N.Left.Height - N.Right.Height| <= 1

 Rebalance(N)
  p <- N.Parent
  if N.Left.Height > N.Right.Height + 1:
    RebalanceRight(N)
  if N.Right.Height > N.Left.Height + 1:
    RebalanceLeft(N)
  AdjustHeight(N)
  if P != null:
    Rebalance(N)

 AdjustHeight(N)
  N.Height <- 1 + max(N.Left.Height + N.Right.Height)

Code

The code is pretty straightforward, we will just implement the operations. It is self explanatory and pretty verbose


//
//  AVLTree.h
//  Data structures
//
//  Created by Lalit Yadav on 06/09/20.
//  Copyright © 2020 Lalit Yadav. All rights reserved.
//

#ifndef AVLTree_h
#define AVLTree_h

#include <iostream>

using namespace std;

struct Node {
  int data;
  int height;
  Node * parent;
  Node * left;
  Node * right;
};

typedef Node * Nodeptr;

class AVLTree {
  Nodeptr root;
  Nodeptr Maximum(Nodeptr node);
  int GetHeight(Nodeptr node);
  void AdjustHeight(Nodeptr node);
  void ReplaceChild(Nodeptr parent, Nodeptr child, Nodeptr new_child);

  void RotateLeft(Nodeptr node);
  void RotateRight(Nodeptr node);

  void Rebalance(Nodeptr node);
  void RebalanceLeft(Nodeptr node);
  void RebalanceRight(Nodeptr node);
  public:
    AVLTree(): root(nullptr) {}
  AVLTree(int key);
  bool IsEmpty();
  Nodeptr Root();
  Nodeptr Find(int key);
  void Insert(int key);
  void Delete(int key);
  void PrintInOrder(Nodeptr node);
  void PrintPreOrder(Nodeptr node);
};

bool AVLTree::IsEmpty() {
  return root == nullptr;
}

Nodeptr AVLTree::Root() {
  return root;
}

Nodeptr AVLTree::Maximum(Nodeptr node) {
  if (node -> right != NULL) {
    return Maximum(node -> right);
  } else {
    return node;
  }
}

int AVLTree::GetHeight(Nodeptr node) {
  if (node == nullptr)
    return 0;

  return node -> height;
}

Nodeptr AVLTree::Find(int key) {
  if (IsEmpty()) {
    return nullptr;
  }

  auto parent = root;

  while (parent != nullptr) {
    if (key > parent -> data && parent -> right != nullptr)
      parent = parent -> right;
    else if (key < parent -> data && parent -> left != nullptr)
      parent = parent -> left;
    else
      return parent;
  }

  return parent;
}

void AVLTree::AdjustHeight(Nodeptr node) {
  node -> height = 1 + max(GetHeight(node -> left), GetHeight(node -> right));
}

void AVLTree::RotateLeft(Nodeptr node) {
  auto pivot = node -> right;

  // Update the parent of the node
  pivot -> parent = node -> parent;
  node -> parent = pivot;

  // Update the child of of the updated parent
  if (pivot -> parent == nullptr)
    root = pivot;
  else if (pivot -> parent -> left == node)
    pivot -> parent -> left = pivot; // Update the child link of the parent
  else
    pivot -> parent -> right = pivot;

  node -> right = pivot -> left;

  if (pivot -> left != nullptr)
    pivot -> left -> parent = node;

  pivot -> left = node;

  AdjustHeight(node);
  AdjustHeight(pivot);
}

void AVLTree::RotateRight(Nodeptr node) {
  auto pivot = node -> left;

  pivot -> parent = node -> parent;
  node -> parent = pivot;

  if (pivot -> parent == nullptr)
    root = pivot;
  else if (pivot -> parent -> left == node)
    pivot -> parent -> left = pivot;
  else
    pivot -> parent -> right = pivot;

  node -> left = pivot -> right;

  if (pivot -> right != nullptr)
    pivot -> right -> parent = node;

  pivot -> right = node;

  AdjustHeight(node);
  AdjustHeight(pivot);
}

void AVLTree::RebalanceLeft(Nodeptr node) {
  auto right_child = node -> right;

  if (right_child != nullptr) {
    if (GetHeight(right_child -> left) > GetHeight(right_child -> right))
      RotateRight(right_child);
  }

  RotateLeft(node);
}

void AVLTree::RebalanceRight(Nodeptr node) {
  auto left_child = node -> left;

  if (left_child != nullptr) {
    if (GetHeight(left_child -> right) > GetHeight(left_child -> left))
      RotateLeft(left_child);
  }

  RotateRight(node);
}

void AVLTree::Rebalance(Nodeptr node) {
  auto parent = node -> parent;

  if (GetHeight(node -> left) > GetHeight(node -> right) + 1)
    RebalanceRight(node);

  if (GetHeight(node -> right) > GetHeight(node -> left) + 1)
    RebalanceLeft(node);

  AdjustHeight(node);

  if (parent != nullptr) {
    Rebalance(parent);
  }
}

void AVLTree::Insert(int key) {
  auto p = new Node;

  p -> data = key;
  p -> height = 0;
  p -> parent = nullptr;
  p -> left = nullptr;
  p -> right = nullptr;

  if (IsEmpty()) {
    root = p;
  } else {
    auto parent = Find(key);
    p -> height = 1;

    if (key < parent -> data)
      parent -> left = p;
    else
      parent -> right = p;

    p -> parent = parent;
    Rebalance(parent);
  }
}

void AVLTree::Delete(int key) {
  auto node = Find(key);

  if (node == nullptr)
    return;

  if (node -> right == nullptr && node -> left == nullptr) {
    if (node -> parent == nullptr) {
      root = nullptr;
    } else {
      ReplaceChild(node -> parent, node, nullptr);
      Rebalance(node -> parent);
    }
  } else if (node -> left == nullptr) {
    // Replace the node with it's right child
    if (node -> parent == nullptr) {
      root = node -> right;
      node -> right -> parent = nullptr;
      Rebalance(node -> right);
    } else {
      ReplaceChild(node -> parent, node, node -> right);
      node -> right -> parent = node -> parent;
      Rebalance(node -> parent);
    }
  } else {
    // Replace the node with the maximum key from it's left child
    auto new_node = Maximum(node -> left);

    if (node -> parent == nullptr) {
      root = new_node;

      new_node -> right = node -> right;
      new_node -> left = node -> left;

      Rebalance(new_node);
    } else {
      auto parent_new_node = new_node -> parent;
      ReplaceChild(node -> parent, node, new_node);
      ReplaceChild(new_node -> parent, new_node, nullptr);

      new_node -> parent = node -> parent;
      new_node -> left = node -> left;

      if (node -> right != nullptr) {
        new_node -> right = node -> right;
        new_node -> right -> parent = new_node;
      }

      if (parent_new_node -> parent == node) {
        parent_new_node -> parent = new_node;
      }

      Rebalance(parent_new_node);
    }
  }

  delete node;
}

void AVLTree::ReplaceChild(Nodeptr parent, Nodeptr child, Nodeptr new_child) {
  if (parent -> left == child) {
    parent -> left = new_child;
  } else {
    parent -> right = new_child;
  }
}

void AVLTree::PrintInOrder(Nodeptr node) {
  if (node == nullptr)
    return;

  PrintInOrder(node -> left);
  cout << node -> data << ' ';
  PrintInOrder(node -> right);
}

void AVLTree::PrintPreOrder(Nodeptr node) {
  if (node == nullptr)
    return;

  cout << node -> data << ' ';
  PrintPreOrder(node -> left);
  PrintPreOrder(node -> right);
}

#endif /* AVLTree_h */


This content originally appeared on DEV Community and was authored by Lalit Yadav


Print Share Comment Cite Upload Translate Updates
APA

Lalit Yadav | Sciencx (2021-06-11T08:28:31+00:00) AVL Tree C++. Retrieved from https://www.scien.cx/2021/06/11/avl-tree-c/

MLA
" » AVL Tree C++." Lalit Yadav | Sciencx - Friday June 11, 2021, https://www.scien.cx/2021/06/11/avl-tree-c/
HARVARD
Lalit Yadav | Sciencx Friday June 11, 2021 » AVL Tree C++., viewed ,<https://www.scien.cx/2021/06/11/avl-tree-c/>
VANCOUVER
Lalit Yadav | Sciencx - » AVL Tree C++. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/06/11/avl-tree-c/
CHICAGO
" » AVL Tree C++." Lalit Yadav | Sciencx - Accessed . https://www.scien.cx/2021/06/11/avl-tree-c/
IEEE
" » AVL Tree C++." Lalit Yadav | Sciencx [Online]. Available: https://www.scien.cx/2021/06/11/avl-tree-c/. [Accessed: ]
rf:citation
» AVL Tree C++ | Lalit Yadav | Sciencx | https://www.scien.cx/2021/06/11/avl-tree-c/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.