Skip to content

Tree 總整理

Binary Search Tree

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

struct BST{
    struct BST *left;
    struct BST *right;
    int val;
};
typedef struct BST BST;

BST* MinValueNode(BST* root){
    BST* current = root;
    while(current && current ->left != NULL){
        current = current->left;
    }
    return current;
}

BST* searchNode(BST* root, int data) {
    if (root == NULL || root->val == data) {
        return root;
    }
    if (data < root->val) {
        return searchNode(root->left, data);
    } else {
        return searchNode(root->right, data);
    }
}


BST* deleteNode(BST *root,int n){
    if(root == NULL)return root;
    if(n < root->val){
        root->left = deleteNode(root->left,n);
    }else if(n > root->val){
        root->right = deleteNode(root->right,n);
    }
    else{
        if(root->left == NULL){
            BST* nextNode = root->right;
            free(root);
            return nextNode;    
        }else if(root->right == NULL){
            BST* nextNode = root->left;
            free(root);
            return nextNode;
        }
        BST *SuccessorNode = MinValueNode(root->right);
        root->val = SuccessorNode->val;
        root->right = deleteNode(root->right,SuccessorNode->val);
    }
    return root;
}



BST* insertNode(BST *root,int n){
    if(root == NULL){
        BST* newNode = (BST *)malloc(sizeof(BST));
        newNode->val = n;
        newNode->left = NULL;
        newNode->right = NULL;
        root = newNode;
        return root;
    }
    if( n > root ->val){
        root->right = insertNode(root->right,n);
    }else if(n < root->val){
        root->left = insertNode(root->left,n);
    }
    return root;
}

void PrintTree(BST *root){
    if(root == NULL)return;
    PrintTree(root->left);
    printf("%d ",root->val);
    PrintTree(root->right);
}

int main(){
    BST *root = NULL;
    root = insertNode(root,1);
    root = insertNode(root,5);
    root = insertNode(root,10);
    root = insertNode(root,100);
    root = insertNode(root,25);

    root = deleteNode(root,10);

    PrintTree(root);


}

AVL Tree

最多的節點數為\(2^H-1\) 最少為 \(N_h = N_{h-1} + N_{h-2} + 1\)

Actual
Insert O(1)
Delete O(logn)

insert

LL RR LR RL 到達的node當做轉換過後的root node 的左子樹當祖父的右子樹 node 的右子樹當作父節點的左子樹

delete

刪掉後看他的父節點變多少

  • case 1 : 1 or -1

    不做任何事

  • case 2 : 2 or -2

    要再看父節點的左子節點

    • case 1 : 0

      做一個LL Rotation

    • case 2 : 1

      做一個LL Rotation

    • case 3 : -1

      做一個LR Rotation

  • case 3 : 0

    因為可能會改變到parent 因此要檢查parenet 是否符合case 2

m-way search tree

Actual
Insert O(logn)
Delete O(logn)

full degree m tree 最大有 \(\frac{m^h - 1}{m-1}\) 個節點 \(m^h-1\)個資料

B-Tree

Balanced m-way search tree

  • root degree >= 2
  • Degree of other internal node >= \(\lceil \frac{m}{2} \rceil\)

insert

先尋找所在的位置 如果overflow 做split 再與父節點結合 直到沒有overflow 的操作

delete

分為是否在葉節點

  • 刪除的資料在葉節點

如果隔壁有可以借的node 就做rotation 不行就做conbine

  • 刪除的資料不在葉節點

左子樹找最大或右子樹找最小

Red-Black Tree

  • 邊會分為黑色或紅色
  • 不會有連續的紅色邊出現
  • 每條路徑經過的黑色邊個數都是相同的
Actual
Insert O(logn)
Delete O(logn)

insert

插入的新點先當成紅色,之後做rr ll rl lr rotation 到達的點當root並且更改為黑色

如果parent 是紅色的 且 他的 sibling 是紅色的 那就把他們都改成黑色 並且檢查parent 是否需要rotation

delete

可以分成 y0 y1 y2

  • y0

    刪除的node 是紅色的或者是由紅色的邊與parent連

    可以直接刪

  • y1

    黑色的邊且child 有紅色的 往有紅色的邊走,直到紅色的邊取代成黑色的為止

  • y2

    黑色的邊 但是child 沒有紅色的 * Type 1 Sibling 是黑色且有紅色的child 刪除node後 做rr * Type 2 Sibling 是黑色且沒有紅色的child 刪除node後 其parent 如果是紅色 parent變黑色與其子樹變紅色 否則parent其子樹變紅色 * Type 3 Sibling 是紅色的 silbing 變成刪除node 的parent 並且交換顏色

B+ Tree

最下層有指標互相連線,上面的node皆變成索引

insert

類似b-tree 但是如果是最底層的需要合併 放在上面的會變成最左邊的值

delete

刪除為空的話跟sibling 借 parent 的索引值要改成sibling的最小值,沒得借直接刪除 刪除如果是空的可以跟隔壁子樹借,隔壁子樹沒辦法借直接conboine