// insert and delete status AVLTreeInsert(AVLTree *tree, ElementType data); status AVLTreeInsertRun(AVLNode **root, ElementType data); status AVLTreeDelete(AVLTree *tree, ElementType data); status AVLTreeDeleteRun(AVLNode **root, ElementType data);
// search status AVLTreeSearch(AVLTree *tree, ElementType data);
// get max and min status AVLTreeGetMax(AVLTree *tree, ElementType *result); status AVLTreeGetMin(AVLTree *tree, ElementType *result);
// get status intAVLTreeGetHeight(AVLTree *tree); intGetNodeHeight(AVLNode *node); intAVLTreeGetSize(AVLTree *tree); status AVLTreeIsEmpty(AVLTree *tree); ElementType GetNodeMin(AVLNode *node); ElementType GetNodeMax(AVLNode *node);
voidAVLTreeDestroy(AVLTree *tree) { if (tree == NULL) { printf("tree is NULL\n"); return; } // recursive destroy AVLTreeDestroyRun(tree->root); free(tree); }
// insert and delete status AVLTreeInsert(AVLTree *tree, ElementType data) { if (tree == NULL) { printf("tree is NULL\n"); return error; } status result = AVLTreeInsertRun(&tree->root, data); // check status if (result == true) { tree->size++; returntrue; } elseif (result == false) returnfalse; return error; }
/* * insert data into AVLTree * return true if insert successfully * return false if insert failed */ status AVLTreeInsertRun(AVLNode **root, ElementType data) { if (*root == NULL) { *root = (AVLNode *) malloc(sizeof(AVLNode)); if (*root == NULL) { printf("malloc failed\n"); return error; } (*root)->data = data; (*root)->height = 1; (*root)->left = (*root)->right = NULL; returntrue; }
if ((*root)->data == data) returnfalse; elseif ((*root)->data < data) { // insert into right subtree status result = AVLTreeInsertRun(&(*root)->right, data); if (result == false) returnfalse; elseif (result == error) return error;
int leftHeight = GetNodeHeight((*root)->left); int rightHeight = GetNodeHeight((*root)->right); // after insert, we need check if the tree is balanced // in this case, we insert into right subtree, // so rightHeight >= leftHeight if (rightHeight - leftHeight == 2) { if ((*root)->right->data < data) { // type RR LeftRotation(root); } else { // type RL RightRotation(&(*root)->right); LeftRotation(root); } } } else { // insert into left subtree status result = AVLTreeInsertRun(&(*root)->left, data); if (result == false) returnfalse; elseif (result == error) return error;
int leftHeight = GetNodeHeight((*root)->left); int rightHeight = GetNodeHeight((*root)->right); // after insert, we need check if the tree is balanced // in this case, we insert into left subtree, // so leftHeight >= rightHeight if (leftHeight - rightHeight == 2) { if ((*root)->left->data > data) { // type LL RightRotation(root); } else { // type LR LeftRotation(&(*root)->left); RightRotation(root); } } } // update height if abs(leftHeight - rightHeight) != 2 (*root)->height = max(GetNodeHeight((*root)->left), GetNodeHeight((*root)->right)) + 1; returntrue; }
status AVLTreeDelete(AVLTree *tree, ElementType data) { if (tree == NULL) { printf("tree is NULL\n"); return error; } status result = AVLTreeDeleteRun(&tree->root, data); // check status if (result == true) { tree->size--; returntrue; } elseif (result == false) returnfalse; return error; }
status AVLTreeDeleteRun(AVLNode **root, ElementType data) { if (*root == NULL) returnfalse; if ((*root)->data == data) { // find the node if ((*root)->left != NULL && (*root)->right != NULL) { // left and right subtree both exist
// find the min node in right subtree and replace the node ElementType key = GetNodeMin((*root)->right); (*root)->data = key;
// delete the min node in right subtree // In effect, the question is shifted to deleting the min node in right subtree AVLTreeDeleteRun(&(*root)->right, key);
int leftHeight = GetNodeHeight((*root)->left); int rightHeight = GetNodeHeight((*root)->right); // after delete, we need check if the tree is balanced // in this case, we delete the min node in right subtree, // so leftHeight >= rightHeight if (leftHeight - rightHeight == 2) { // check >= , not > if (GetNodeHeight((*root)->left->left) >= GetNodeHeight((*root)->left->right)) { // type LL RightRotation(root); } else { // type LR LeftRotation(&(*root)->left); RightRotation(root); } } } elseif ((*root)->left == NULL) { // left subtree is empty AVLNode *temp = *root; *root = (*root)->right; free(temp); temp = NULL; returntrue; } else { // right subtree is empty AVLNode *temp = *root; *root = (*root)->left; free(temp); temp = NULL; returntrue; } } elseif ((*root)->data < data) { // find in right subtree status result = AVLTreeDeleteRun(&(*root)->right, data); if (result == false) returnfalse; elseif (result == error) return error;
int leftHeight = GetNodeHeight((*root)->left); int rightHeight = GetNodeHeight((*root)->right); // after delete, we need check if the tree is balanced // in this case, we delete in right subtree, // so leftHeight >= rightHeight if (leftHeight - rightHeight == 2) { // check >= , not > if (GetNodeHeight((*root)->left->left) >= GetNodeHeight((*root)->left->right)) { // type LL RightRotation(root); } else { // type LR LeftRotation(&(*root)->left); RightRotation(root); } } } else { // find in left subtree status result = AVLTreeDeleteRun(&(*root)->left, data); if (result == false) returnfalse; elseif (result == error) return error;
int leftHeight = GetNodeHeight((*root)->left); int rightHeight = GetNodeHeight((*root)->right); // after delete, we need check if the tree is balanced // in this case, we delete in left subtree, // so rightHeight >= leftHeight if (rightHeight - leftHeight == 2) { // check >= , not > if (GetNodeHeight((*root)->right->right) >= GetNodeHeight((*root)->right->left)) { // type RR LeftRotation(root); } else { // type RL RightRotation(&(*root)->right); LeftRotation(root); } } }