void Insert(AVLTree &root,KEY_TYPE key){ if (root == NULL) { root = (AVL*)malloc(sizeof(AVL)); root->key = key; root->lchild = NULL; root->rchild = NULL; root->height = 0; return; }else{ if (root->key < key) { Insert(root->rchild, key); }else if(root->key > key){ Insert(root->lchild, key); } root->height = max(GetHeight(root->lchild), GetHeight(root->rchild)) + 1; if (GetHeight(root->lchild) - GetHeight(root->rchild) == 2) { if (root->lchild->key < key) { LR_Rotate(root); }else{ LL_Rotate(root); } }else if (GetHeight(root->rchild) - GetHeight(root->lchild) == 2) { if (root->rchild->key < key) { RR_Rotate(root); }else{ RL_Rotate(root); } } } }
/* return which the root pointer(at an outer/higher level) should point to, the root_node of AVL tree may change frequently during delete/insert, so the Root pointer should point to the REAL root node. */ AVL* Insert(AVL* root, KEY_TYPE key) { if(root == NULL) return (root = New_Node(key, NULL, NULL)); else if(key < root->key) root->lchild = Insert(root->lchild, key); else //key >= root->key root->rchild = Insert(root->rchild, key); root->height = max(getHeight(root->lchild), getHeight(root->rchild)) + 1; if(getHeight(root->lchild) - getHeight(root->rchild) == 2) { if(key < root->lchild->key) root = RR_Rotate(root); else root = LR_Rotate(root); } else if(getHeight(root->rchild) - getHeight(root->lchild) == 2) { if(key < root->rchild->key) root = RL_Rotate(root); else root = LL_Rotate(root); } return root; }
AVL* check_and_rorate(AVL * rnode, AVL* parent) { AVL * rret = rnode; if (rnode == NULL) return; if (rnode->height >= 2) { //left tree height than right if(rnode->lchild != NULL && rnode->lchild->lchild != NULL) { rret = LL_Rotate(rnode); } else if(rnode->lchild != NULL && rnode->lchild->rchild != NULL) { rret = LR_Rotate(rnode); } if (parent != NULL) { set_parent(rret, rnode, parent); } } else if (rnode->height <= -2) { //right tree height than left if (rnode->rchild != NULL && rnode->rchild->rchild != NULL) { rret = RR_Rotate(rnode); } else if (rnode->rchild != NULL && rnode->rchild->lchild != NULL) { rret = RL_Rotate(rnode); } if (parent != NULL) { set_parent(rret, rnode, parent); } } return rret; }
void Delete(AVLTree &root,KEY_TYPE key){ if (root == NULL) { return; } if (root->key == key) { AVLTree toFree = root; if (root->lchild == NULL && root->rchild == NULL) { root = NULL; }else if(root->lchild != NULL && root->rchild != NULL){ AVLTree loop = root->rchild; while (loop->lchild != NULL) { loop = loop->lchild; } root->key = loop->key; Delete(root->rchild, loop->key); }else{ if (root->lchild!=NULL) { root = root->lchild; }else{ root = root->rchild; } } free(toFree); }else if(root->key < key){ Delete(root->rchild, key); }else{ Delete(root->lchild, key); } if(root==NULL){ return; } root->height = max(GetHeight(root->lchild),GetHeight(root->rchild)) + 1; if (GetHeight(root->lchild) - GetHeight(root->rchild) == 2) { if (root->lchild->key < key) { LR_Rotate(root); }else{ LL_Rotate(root); } }else if (GetHeight(root->rchild) - GetHeight(root->lchild) == 2) { if (root->rchild->key < key) { RR_Rotate(root); }else{ RL_Rotate(root); } } }
/* return which the root pointer(at an outer/higher level) should pointer to, cause the root_node of AVL tree may change frequently during delete/insert, so the Root pointer should point to the REAL root node. */ AVL* Delete(AVL* root, KEY_TYPE key) { if(!root) return NULL; if(key == root->key) { if(root->rchild == NULL) { AVL* temp = root; root = root->lchild; delete(temp); return root; } else { AVL* temp = root->rchild; while(temp->lchild) temp = temp->lchild; /* replace the value */ root->key = temp->key; /* Delete the node (successor node) that should be really deleted */ root->rchild = Delete(root->rchild, temp->key); } } else if(key < root->key) root->lchild = Delete(root->lchild, key); else root->rchild = Delete(root->rchild, key); root->height = max(getHeight(root->lchild), getHeight(root->rchild)) + 1; if(getHeight(root->rchild) - getHeight(root->lchild) == 2) { if(getHeight(root->rchild->rchild) >= getHeight(root->rchild->lchild)) root = LL_Rotate(root); else root = RL_Rotate(root); } else if(getHeight(root->lchild) - getHeight(root->rchild) == 2) { if(getHeight(root->lchild->lchild) >= getHeight(root->lchild->rchild)) root = RR_Rotate(root); else root = LR_Rotate(root); } return root; }
AVL* Balance(AVL* root){ if (root != NULL){ if (getHeight(root->lchild) - 1 > getHeight(root->rchild)){ if (getHeight(root->lchild->lchild) > getHeight(root->lchild->rchild)){ root = LL_Rotate(root); } else { root = LR_Rotate(root); } } else if (getHeight(root->rchild) - 1 > getHeight(root->lchild)){ if (getHeight(root->rchild->rchild) > getHeight(root->rchild->lchild)){ root = RR_Rotate(root); } else { root = RL_Rotate(root); } } else { root->height = setHeight(root); } } return root; }