Menu
CoddyTech

Chèn

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

insert ban đầu hoạt động như thao tác chèn thông thường của cây tìm kiếm nhị phân (binary search tree): đi xuống, so sánh các giá trị, rẽ trái hoặc phải, rồi đặt nút mới vào vị trí null còn trống (bỏ qua các giá trị trùng lặp). Phần AVL diễn ra khi đi ngược lên: sau khi đặt nút, mỗi nút tổ tiên trên đường đi sẽ tính lại height và kiểm tra hệ số cân bằng (balance factor).

Nếu một nút mất cân bằng, phía nào nặng hơn và giá trị mới nằm ở đâu sẽ cùng quyết định trường hợp nào trong bốn trường hợp áp dụng: trái-trái và phải-phải cần một phép xoay, còn trái-phải và phải-trái cần hai phép xoay: phép xoay bên trong để làm thẳng đường zig-zag, sau đó là phép xoay bên ngoài.

challenge icon

Thử thách

Trung bình

Viết phương thức insert(value) trong AVLTree (dùng hàm trợ giúp đệ quy là cách gọn nhất). Chèn value như trong cây BST thông thường, bỏ qua nếu giá trị này đã có. Khi quay ngược lên, tính lại chiều cao và hệ số cân bằng của từng nút. Nếu nút nào mất cân bằng, hãy áp dụng phép xoay phù hợp (hoặc cặp phép xoay) trước khi trả về ngăn xếp lời gọi.

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, "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");
        }
        if (parsed >= 1 && strcmp(cmd, "height") == 0) {
            printf("%d\n", AVLTree_getHeight(tree, tree->root));
        }
    }
    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