Menu
CoddyTech

Xóa

Bài học 11 trên 16 trong khóa học Cây AVL, chuỗi cấu trúc dữ liệu #10 của Coddy.

Xóa trong BST cũng giống như xóa trong cây tìm kiếm nhị phân, với cách cân bằng lại tương tự thao tác chèn. Có ba trường hợp cần xử lý cho nút bị xóa: không có nút con (chỉ cần xóa nút đó), có một nút con (thay nút đó bằng nút con ấy) hoặc có hai nút con, đây là trường hợp khó hơn. Khi đó, bạn thay giá trị của nút bằng nút kế nhiệm theo thứ tự trung tố (giá trị nhỏ nhất trong cây con bên phải), rồi xóa nút kế nhiệm đó khỏi cây con bên phải.

Cũng như khi chèn, mỗi nút tổ tiên trên đường đi ngược lên sẽ tính lại chiều cao và hệ số cân bằng, rồi áp dụng kiểu xoay phù hợp nếu cây mất cân bằng. Logic cân bằng lại giống hệt khi chèn, chỉ khác là điều kiện chọn kiểu xoay giờ dựa vào hệ số cân bằng của nút con nặng hơn, thay vì vị trí mà giá trị mới được chèn vào.

challenge icon

Thử thách

Trung bình

Viết phương thức delete(value) cho AVLTree (dùng một hàm trợ giúp đệ quy sẽ phù hợp). Xóa value theo cách xóa BST thông thường: với nút có hai nút con, thay giá trị của nút bằng giá trị nhỏ nhất trong cây con bên phải, rồi xóa giá trị đó khỏi cây con bên phải. Không làm gì nếu không tìm thấy value. Khi quay ngược lên, tính lại chiều cao và cân bằng lại giống hệt như cách insert thực hiện.

Tự làm thử

#include <stdio.h>
#include <string.h>
#include "avltree.h"

static void preorderValues(Node* node, int* vals, int* count) {
    if (node == NULL) {
        return;
    }
    vals[(*count)++] = node->value;
    preorderValues(node->left, vals, count);
    preorderValues(node->right, vals, count);
}

int main(void) {
    AVLTree* tree = AVLTree_create();
    char line[256];
    while (fgets(line, sizeof(line), stdin) != NULL) {
        line[strcspn(line, "\r\n")] = '\0';
        char cmd[32];
        int arg;
        int parsed = sscanf(line, "%31s %d", cmd, &arg);
        if (parsed >= 1 && strcmp(cmd, "insert") == 0) {
            AVLTree_insert(tree, arg);
        }
        if (parsed >= 1 && strcmp(cmd, "delete") == 0) {
            AVLTree_delete(tree, arg);
        }
        if (parsed >= 1 && strcmp(cmd, "search") == 0) {
            if (AVLTree_search(tree, arg)) {
                printf("true\n");
            }
            if (!AVLTree_search(tree, arg)) {
                printf("false\n");
            }
        }
        if (parsed >= 1 && strcmp(cmd, "preorder") == 0) {
            int vals[10000];
            int count = 0;
            preorderValues(tree->root, vals, &count);
            for (int i = 0; i < count; i++) {
                if (i > 0) {
                    printf(" ");
                }
                printf("%d", vals[i]);
            }
            printf("\n");
        }
    }
    return 0;
}

Tất cả bài học trong Cây AVL, chuỗi cấu trúc dữ liệu #10

Tự luyện tập: Trình biên dịch C online