1. 程式人生 > >AVL樹介紹與實現

AVL樹介紹與實現

複製程式碼
/* 
 * 刪除結點(z),返回根節點
 *
 * 引數說明:
 *     ptree AVL樹的根結點
 *     z 待刪除的結點
 * 返回值:
 *     根節點
 */
static Node* delete_node(AVLTree tree, Node *z)
{
    // 根為空 或者 沒有要刪除的節點,直接返回NULL。
    if (tree==NULL || z==NULL)
        return NULL;

    if (z->key < tree->key)        // 待刪除的節點在"tree的左子樹"中
    {
        tree
->left = delete_node(tree->left, z); // 刪除節點後,若AVL樹失去平衡,則進行相應的調節。 if (HEIGHT(tree->right) - HEIGHT(tree->left) == 2) { Node *r = tree->right; if (HEIGHT(r->left) > HEIGHT(r->right)) tree = right_left_rotation(tree);
else tree = right_right_rotation(tree); } } else if (z->key > tree->key)// 待刪除的節點在"tree的右子樹"中 { tree->right = delete_node(tree->right, z); // 刪除節點後,若AVL樹失去平衡,則進行相應的調節。 if (HEIGHT(tree->left) - HEIGHT(tree->right) == 2) { Node
*l = tree->left; if (HEIGHT(l->right) > HEIGHT(l->left)) tree = left_right_rotation(tree); else tree = left_left_rotation(tree); } } else // tree是對應要刪除的節點。 { // tree的左右孩子都非空 if ((tree->left) && (tree->right)) { if (HEIGHT(tree->left) > HEIGHT(tree->right)) { // 如果tree的左子樹比右子樹高; // 則(01)找出tree的左子樹中的最大節點 // (02)將該最大節點的值賦值給tree。 // (03)刪除該最大節點。 // 這類似於用"tree的左子樹中最大節點"做"tree"的替身; // 採用這種方式的好處是:刪除"tree的左子樹中最大節點"之後,AVL樹仍然是平衡的。 Node *max = avltree_maximum(tree->left); tree->key = max->key; tree->left = delete_node(tree->left, max); } else { // 如果tree的左子樹不比右子樹高(即它們相等,或右子樹比左子樹高1) // 則(01)找出tree的右子樹中的最小節點 // (02)將該最小節點的值賦值給tree。 // (03)刪除該最小節點。 // 這類似於用"tree的右子樹中最小節點"做"tree"的替身; // 採用這種方式的好處是:刪除"tree的右子樹中最小節點"之後,AVL樹仍然是平衡的。 Node *min = avltree_maximum(tree->right); tree->key = min->key; tree->right = delete_node(tree->right, min); } } else { Node *tmp = tree; tree = tree->left ? tree->left : tree->right; free(tmp); } } return tree; } /* * 刪除結點(key是節點值),返回根節點 * * 引數說明: * tree AVL樹的根結點 * key 待刪除的結點的鍵值 * 返回值: * 根節點 */ Node* avltree_delete(AVLTree tree, Type key) { Node *z; if ((z = avltree_search(tree, key)) != NULL) tree = delete_node(tree, z); return tree; }