AVLCommands.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include "AVLCommand.h"
  2. // examples of AVL tree algorithms:
  3. // https://tfetimes.com/c-avl-tree/
  4. // https://stackoverflow.com/questions/29866315/class-for-avl-trees-c
  5. // http://www.sanfoundry.com/cpp-program-implement-avl-trees/
  6. // AVL explanation:
  7. // http://www.btechsmartclass.com/DS/U5_T2.html
  8. // combination of geeksforgeeks AVL insert and delete code
  9. // written for C
  10. // => convert into a C++ class
  11. // An AVL tree node struct that is probably useless to me
  12. struct Node { // already have a struct inside BST...
  13. // maybe no pointers in here...
  14. // but then why bother with a struct :/
  15. int key;
  16. //struct Node *left;
  17. //struct Node *right;
  18. int height;
  19. };
  20. // constructor: builds an AVL tree from BST tree bst
  21. AVLCommands::AVLCommands() {
  22. BST bst(); // initialize BST with root null and sized 0
  23. }
  24. void AVLCommands::Insert(int key) {
  25. // normal BST insertion
  26. bst.Insert(key);
  27. // update height of ancestor node
  28. // geeksforgeeks C:
  29. node->height = 1 + max(height(node->left),
  30. height(node->right));
  31. // check if the tree is unbalanced by checking
  32. // ancestor balance factor
  33. // if unbalanced
  34. // left-left
  35. // right-right
  36. // left-right
  37. // right-left
  38. }
  39. // Recursive function to insert key in subtree rooted
  40. // with node and returns new root of subtree.
  41. struct Node* insert(struct Node* node, int key)
  42. {
  43. /* 1. Perform the normal BST insertion */
  44. if (node == NULL)
  45. return(newNode(key));
  46. if (key < node->key)
  47. node->left = insert(node->left, key);
  48. else if (key > node->key)
  49. node->right = insert(node->right, key);
  50. else // Equal keys are not allowed in BST
  51. return node;
  52. /* 2. Update height of this ancestor node */
  53. node->height = 1 + max(height(node->left),
  54. height(node->right));
  55. /* 3. Get the balance factor of this ancestor
  56. node to check whether this node became
  57. unbalanced */
  58. int balance = getBalance(node);
  59. // If this node becomes unbalanced, then
  60. // there are 4 cases
  61. // Left Left Case
  62. if (balance > 1 && key < node->left->key)
  63. return rightRotate(node);
  64. // Right Right Case
  65. if (balance < -1 && key > node->right->key)
  66. return leftRotate(node);
  67. // Left Right Case
  68. if (balance > 1 && key > node->left->key)
  69. {
  70. node->left = leftRotate(node->left);
  71. return rightRotate(node);
  72. }
  73. // Right Left Case
  74. if (balance < -1 && key < node->right->key)
  75. {
  76. node->right = rightRotate(node->right);
  77. return leftRotate(node);
  78. }
  79. /* return the (unchanged) node pointer */
  80. return node;
  81. }
  82. // A utility function to get maximum of two integers
  83. int max(int a, int b);
  84. // A utility function to get height of the tree
  85. int height(struct Node *N) {
  86. if (N == NULL)
  87. return 0;
  88. return N->height;
  89. }
  90. // A utility function to get maximum of two integers
  91. int max(int a, int b) {
  92. return (a > b)? a : b;
  93. }
  94. /* Helper function that allocates a new node with the given key and
  95. NULL left and right pointers. */
  96. struct Node* newNode(int key)
  97. {
  98. struct Node* node = (struct Node*)
  99. malloc(sizeof(struct Node));
  100. node->key = key;
  101. node->left = NULL;
  102. node->right = NULL;
  103. node->height = 1; // new node is initially added at leaf
  104. return(node);
  105. }
  106. // A utility function to right rotate subtree rooted with y
  107. // See the diagram given above.
  108. struct Node *rightRotate(struct Node *y)
  109. {
  110. struct Node *x = y->left;
  111. struct Node *T2 = x->right;
  112. // Perform rotation
  113. x->right = y;
  114. y->left = T2;
  115. // Update heights
  116. y->height = max(height(y->left), height(y->right))+1;
  117. x->height = max(height(x->left), height(x->right))+1;
  118. // Return new root
  119. return x;
  120. }
  121. // A utility function to left rotate subtree rooted with x
  122. // See the diagram given above.
  123. struct Node *leftRotate(struct Node *x)
  124. {
  125. struct Node *y = x->right;
  126. struct Node *T2 = y->left;
  127. // Perform rotation
  128. y->left = x;
  129. x->right = T2;
  130. // Update heights
  131. x->height = max(height(x->left), height(x->right))+1;
  132. y->height = max(height(y->left), height(y->right))+1;
  133. // Return new root
  134. return y;
  135. }
  136. // Get Balance factor of node N
  137. int getBalance(struct Node *N)
  138. {
  139. if (N == NULL)
  140. return 0;
  141. return height(N->left) - height(N->right);
  142. }
  143. /* Given a non-empty binary search tree, return the
  144. node with minimum key value found in that tree.
  145. Note that the entire tree does not need to be
  146. searched. */
  147. struct Node * minValueNode(struct Node* node)
  148. {
  149. struct Node* current = node;
  150. /* loop down to find the leftmost leaf */
  151. while (current->left != NULL)
  152. current = current->left;
  153. return current;
  154. }
  155. // Recursive function to delete a node with given key
  156. // from subtree with given root. It returns root of
  157. // the modified subtree.
  158. struct Node* deleteNode(struct Node* root, int key)
  159. {
  160. // STEP 1: PERFORM STANDARD BST DELETE
  161. if (root == NULL)
  162. return root;
  163. // If the key to be deleted is smaller than the
  164. // root's key, then it lies in left subtree
  165. if ( key < root->key )
  166. root->left = deleteNode(root->left, key);
  167. // If the key to be deleted is greater than the
  168. // root's key, then it lies in right subtree
  169. else if( key > root->key )
  170. root->right = deleteNode(root->right, key);
  171. // if key is same as root's key, then This is
  172. // the node to be deleted
  173. else
  174. {
  175. // node with only one child or no child
  176. if( (root->left == NULL) || (root->right == NULL) )
  177. {
  178. struct Node *temp = root->left ? root->left :
  179. root->right;
  180. // No child case
  181. if (temp == NULL)
  182. {
  183. temp = root;
  184. root = NULL;
  185. }
  186. else // One child case
  187. *root = *temp; // Copy the contents of
  188. // the non-empty child
  189. free(temp);
  190. }
  191. else
  192. {
  193. // node with two children: Get the inorder
  194. // successor (smallest in the right subtree)
  195. struct Node* temp = minValueNode(root->right);
  196. // Copy the inorder successor's data to this node
  197. root->key = temp->key;
  198. // Delete the inorder successor
  199. root->right = deleteNode(root->right, temp->key);
  200. }
  201. }
  202. // If the tree had only one node then return
  203. if (root == NULL)
  204. return root;
  205. // STEP 2: UPDATE HEIGHT OF THE CURRENT NODE
  206. root->height = 1 + max(height(root->left),
  207. height(root->right));
  208. // STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to
  209. // check whether this node became unbalanced)
  210. int balance = getBalance(root);
  211. // If this node becomes unbalanced, then there are 4 cases
  212. // Left Left Case
  213. if (balance > 1 && getBalance(root->left) >= 0)
  214. return rightRotate(root);
  215. // Left Right Case
  216. if (balance > 1 && getBalance(root->left) < 0)
  217. {
  218. root->left = leftRotate(root->left);
  219. return rightRotate(root);
  220. }
  221. // Right Right Case
  222. if (balance < -1 && getBalance(root->right) <= 0)
  223. return leftRotate(root);
  224. // Right Left Case
  225. if (balance < -1 && getBalance(root->right) > 0)
  226. {
  227. root->right = rightRotate(root->right);
  228. return leftRotate(root);
  229. }
  230. return root;
  231. }