AVL樹介紹與實現
阿新 • • 發佈:2018-12-25
/* * 刪除結點(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; }