#include <stdio.h> #include <malloc.h> /** * 二叉樹是比較高效的存取結構 * 單次操作的時間複雜度爲O(logN),N爲總元素個數 * 二叉搜索樹滿足一下特點: * 左子樹上的所有節點都比自己小 * 右子樹上的所有節點都比自己大 */ //定義數樹的節點 typedef struct Node{ int val; //值 struct Node *lc; //左兒子 struct Node *rc; //右兒子 } Node; Node *new_Node(int val){ Node *node = malloc(sizeof(Node)); node->lc = NULL; node->rc = NULL; node->val = val; return node; } //二叉搜索樹 typedef struct Bst{ struct Node *root; void (*insert)(struct Bst *, int); int (*find)(struct Bst *, int); Node *(*delete)(struct Bst *, int); } Bst; //插入節點 void insert(Bst *this, int val){ Node **cur_node = &(this->root); while ((*cur_node) != NULL){ if (val < (*cur_node)->val){ (cur_node) = &((*cur_node)->lc); } else { (cur_node) = &((*cur_node)->rc); } } (*cur_node) = new_Node(val); } //查找是否有該節點,返回0代表沒有,1代表有 int find(Bst *this, int val){ Node *cur_node = this->root; while (cur_node != NULL){ if (val < cur_node->val){ cur_node = cur_node->lc; } else if (val > cur_node->val){ cur_node = cur_node->rc; } else { return 1; } } return 0; } //刪除節點 Node *delete(Bst *this, int val) { Node **cur_node = &(this->root); //不斷向下尋找 while ((*cur_node) != NULL) { if (val < (*cur_node)->val){ (cur_node) = &((*cur_node)->lc); } else if (val > (*cur_node)->val){ (cur_node) = &((*cur_node)->rc); } //如果找到要刪除的節點 else { //如果要刪除的節點左兒子爲空,那就把右兒子補到當前節點上 if ((*cur_node)->lc == NULL){ Node *q = (*cur_node)->rc; Node *temp = *cur_node; (*cur_node) = q; free(temp); return q; } //如果要刪除的節點左兒子沒有右兒子,那就把左兒子補到當前節點上 else if ((*cur_node)->lc->rc == NULL){ Node *q = (*cur_node)->lc; q->rc = (*cur_node)->rc; Node *temp = *cur_node; (*cur_node) = q; free(temp); return q; } //其餘情況:把左兒子的子孫中最大的節點補到要刪除的節點上 else { Node *q = (*cur_node)->lc; while (q->rc != NULL){ q = q->rc; } Node *temp = *cur_node; q->rc = (*cur_node)->rc; q->lc = (*cur_node)->lc; (*cur_node) = q; free(temp); return q; } } } return NULL; } Bst *new_Bst(){ Bst *bst = malloc(sizeof(Bst)); bst->root = NULL; bst->insert = &insert; bst->find = &find; bst->delete = &delete; return bst; } int main() { Bst *bst = new_Bst(); bst->insert(bst, 2); bst->insert(bst, 1); bst->insert(bst, 2); bst->insert(bst, 3); printf("%d\n", bst->find(bst, 2)); bst->delete(bst, 2); bst->delete(bst, 2); printf("%d\n", bst->find(bst, 2)); return 0; }
運行結果:
1
0