AVL樹C實現

#include <stdlib.h>
#include <stdio.h>
#include <memory.h>

typedef struct S_Node {
    struct S_Node * left;
    struct S_Node * right;
    int value;
    int factor;		//平衡因子
} Node;

typedef struct S_Queue {
    struct S_Queue * next;
    void * data;
} Queue;


Node* find(Node* root, int value);
int do_remove_node(Node ** proot, int value, int * shorter);
void balance(Node** proot);
void queue_put(Queue** phead, void * data);
void* queue_peek(Queue ** phead);
void remove_node(Node * proot, int value);

void do_level_travel(Queue * head);
void level_travel(Node * root);


void balance(Node** proot) {
    Node * temp = NULL;
    Node * root = *proot;
    if (root->factor == 2) {//l
        if (root->left->factor == 1) {  //LL
            temp = root->left;
            root->left = temp->right;
            temp->right = root;
            //factor的調整
            temp->factor = 0;
            temp->right->factor = 0;
        }
        else if (root->left->factor == -1) {  //LR
            Node* tl = root->left;
            root->left = tl->right;
            tl->right = NULL;
            root->left->left = tl;

            temp = root->left;
            root->left = temp->right;
            temp->right = root;
            //factor的調整
            temp->factor = 0;
            temp->right->factor = 0;
            if (temp->left->left != NULL) temp->left->factor = 1;
            else temp->left->factor = 0;
        }
    }
    else if (root->factor == -2) {//r
        if (root->right->factor == -1) { //RR
            temp = root->right;
            root->right = temp->left;
            temp->left = root;
            //factor的調整
            temp->factor = 0;
            temp->left->factor = 0;
        }
        else if (root->right->factor == 1) { //RL
            Node* tr = root->right;
            root->right = tr->left;
            tr->left = NULL;
            root->right->right = tr;

            temp = root->right;
            root->right = temp->left;
            temp->left = root;

            temp->factor = 0;
            temp->left->factor = 0;
            if (temp->right->right != NULL) temp->right->factor = -1;
            else temp->right->factor = 0;
        }
    }
    *proot = temp;
}

void insert(Node** proot, int value, int * height_change) {
    Node * root = *proot;
    if (root != NULL) {
        if (value < root->value) {
            if (root->left == NULL) {
                Node * temp = (Node *)malloc(sizeof(Node));
                temp->right = NULL;
                temp->left = NULL;
                temp->value = value;
                temp->factor = 0;
                root->left = temp;
                root->factor++;
                if (root->factor == 0) *height_change = 0;
            }
            else {
                insert(&root->left, value, height_change);
                if(*height_change == 1) root->factor++;
            }
        }
        else if(value > root->value) {
            if (root->right == NULL) {
                Node * temp = (Node *)malloc(sizeof(Node));
                temp->right = NULL;
                temp->left = NULL;
                temp->value = value;
                temp->factor = 0;
                root->right = temp;
                root->factor--;
                if (root->factor == 0) *height_change = 0;
            }
            else {
                insert(&root->right, value, height_change);
                if (*height_change == 1) root->factor--;
            }
        }
        else {
            printf("%s\n", "node cant be duplicated");
            return;
        }

        if (root->factor == 2 || root->factor == -2) {
            balance(proot);
            *height_change = 0;
        }
    }
}

int do_remove_node(Node ** proot, int value, int * shorter) {	//shorter初始化0
    Node * root = *proot;
    if (root == NULL) {
        return 0;
    }
    if (value < root->value) {	//左子樹遞歸搜索

        if (do_remove_node(&root->left, value, shorter) == 0) {
            return 0;
        }
        if (*shorter == 1) {
            switch (root->factor) {
                case 1:
                    root->factor = 0;
                    *shorter = 1;
                    break;
                case 0:
                    root->factor = -1;
                    *shorter = 0;
                    break;
                case -1:
                    if (root->right->factor == 0)
                        *shorter = 0;
                    else
                        *shorter = 1;
                    root->factor = -2;
                    balance(proot);    //右平衡處理
                    break;
            }
        }
    }

    else if (value > root->value) {	//右子樹遞歸搜索
        if (do_remove_node(&root->right, value, shorter) == 0) return 0;
        if (*shorter == 1) {
            switch (root->factor) {
                case 1:
                    if (root->left->factor == 0)
                        *shorter = 0;
                    else
                        *shorter = 1;
                    root->factor = 2;
                    balance(proot);
                    break;
                case 0:
                    root->factor = 1;
                    *shorter = 0;
                    break;
                case -1:
                    root->factor = 0;
                    *shorter = 1;
                    break;
            }
        }
    }

    else {	//root是需要刪除的節點
        if (root->left == NULL) {
            *proot = root->right;
            free(root);
            *shorter = 1;
        }
        else if (root->right == NULL) {
            *proot = root->left;
            free(root);
            *shorter = 1;
        }
        else {
            /*Node * l = root->left;
            while (l->right) {
                l = l->right;
            }
            root->value = l->value;
            do_remove_node(&root->left, l->value, shorter);
            if (*shorter == 1) {
                switch (root->factor) {
                case 1:
                    root->factor = 0;
                    *shorter = 1;
                    break;
                case 0:
                    root->factor = -1;
                    *shorter = 0;
                    break;
                case -1:
                    if (root->right->factor == 0)
                        *shorter = 0;
                    else
                        *shorter = 1;
                    balance(proot);    //右平衡處理
                    break;
                }
            }*/
            Node * r = root->right;
            while (r->left != NULL) r = r->left;
            root->value = r->value;
            do_remove_node(&root->right, r->value, shorter);
            if (*shorter == 1) {
                switch (root->factor) {
                    case 1:
                        if (root->left->factor == 0)
                            *shorter = 0;
                        else
                            *shorter = 1;
                        root->factor = 2;
                        balance(proot);
                        break;
                    case 0:
                        root->factor = 1;
                        *shorter = 0;
                        break;
                    case -1:
                        root->factor = 0;
                        *shorter = 1;
                        break;
                }
            }
        }

    }
    return 1;
}

void remove_node(Node * root, int value) {
    int * shorter = (int *)malloc(sizeof(int));
    memset(shorter, 0, sizeof(shorter));
    do_remove_node(&root, value, shorter);
}

Node* create_tree(int * values, int len) {
    Node * head = NULL;
    if (values != NULL) {
        int i;
        for (i = 0; i < len; ++i) {
            int * heigh_change = (int *)malloc(sizeof(int));
            *heigh_change = 1;
            if (head == NULL) {
                head = (Node*)malloc(sizeof(Node));
                head->value = values[i];
                head->left = NULL;
                head->right = NULL;
                head->factor = 0;
            }
            else insert(&head, values[i], heigh_change);
        }
    }
    return head;
}

Node* find(Node* root, int value) {
    if (root != NULL) {
        if (value == root->value) return root;
        if (value < root->value) {
            return find(root->left, value);
        }
        else {
            return find(root->right, value);
        }
    }
    return NULL;
}

int height(Node * root) {
    if (root != NULL) {
        int left_h = height(root->left), right_h = height(root->right);
        return 1 + (left_h > right_h ? left_h : right_h);
    }
    else return 0;
}

void pre_travel(Node * root) {
    if (root != NULL) {
        printf("%d\n", root->value);
        pre_travel(root->left);
        pre_travel(root->right);
    }
}

void order_travel(Node * root) {
    if (root != NULL) {
        order_travel(root->left);
        printf("%d ", root->value);
        order_travel(root->right);
    }
}

void post_travel(Node * root) {
    if (root != NULL) {
        post_travel(root->left);
        post_travel(root->right);
        printf("%d\n", root->value);
    }
}

void do_level_travel(Queue * head) {
    if (head != NULL) {
        Node * root = (Node *) queue_peek(&head);
        if (root != NULL) {
            printf("%d ", root->value);
            if(root->left != NULL) queue_put(&head, root->left);
            if (root->right != NULL) queue_put(&head, root->right);
            do_level_travel(head);
        }
    }
}

void level_travel(Node * root) {
    Queue * q = (Queue*)malloc(sizeof(Queue));
    q->data = root;
    q->next = NULL;
    do_level_travel(q);
}


void queue_put(Queue** phead, void * data) {
    Queue * head = *phead;
    if (head != NULL) {
        while (head->next != NULL) {
            head = head->next;
        }
        Queue * t = (Queue*)malloc(sizeof(Queue));
        t->data = data;
        t->next = NULL;
        head->next = t;
    }
    else {
        Queue * t = (Queue*)malloc(sizeof(Queue));
        t->data = data;
        t->next = NULL;
        *phead = t;
    }
}
void* queue_peek(Queue ** phead) {
    Queue * head = *phead;
    if (head != NULL) {
        void * res = head->data;
        *phead = head->next;
        free(head);
        return res;
    }
    return NULL;
}

int main() {
    //測試
    int len = 10;
    int nodes[10] = { 5,13,7,9,1,3,10,15,20,25 };
    Node * root = create_tree(nodes, len);
    order_travel(root);
    printf("\n");

    level_travel(root);
    printf("\n");

    remove_node(root, 7);
    order_travel(root);
    printf("\n");

    remove_node(root, 15);
    order_travel(root);
    printf("\n");

    remove_node(root, 20);
    order_travel(root);
    printf("\n");

    printf("%d", height(root));


    scanf("%d", &len);
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章