이진 탐색 트리(Binary Search Tree)
- 기본적인 접근
Search()는 대소 비교를 하면서 해당 값과 같은 Node 찾기
Insert()는 대소를 비교해서 빈 자리에 Insert , Tree가 비어있을 때 예외처리.
Delete()는 3가지 경우로 나눠서 접근 (삭제할 값이 없는 경우 예외처리)
1. 자식이 없는 경우 – 그냥 삭제
2. 자식이 1개인 경우 – 부모와 교환 ,자식 데이터 delete 함수로 삭제(재귀)
3. 자식이 2개인 경우 – 오른쪽에서 가장 왼쪽 값이나, 왼쪽에서 가장 오른쪽 값이랑 교환, 바꾼 값을 delete 함수로 삭제(재귀)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | #include<stdio.h> #include<stdlib.h> typedef struct node { int data; node* left, *right,*p; }node; node* insert(node** root, int data); void del(node** root, int data); node* search(node** root, int data); void print(node* root); node* max_min(node** root); int main() { node* root = NULL; insert(&root, 15); insert(&root, 6); insert(&root, 18); insert(&root, 3); insert(&root, 7); insert(&root, 17); insert(&root, 2); insert(&root, 4); insert(&root, 13); insert(&root, 9); insert(&root, 20); print(root); puts(""); del(&root, 9); print(root); puts(""); del(&root, 7); print(root); del(&root, 15); puts(""); print(root); return 0; } node* search(node** root, int data) { node* ret = (node*)malloc(sizeof(node)); if (root == NULL) { printf("찾으려는 값이 트리에 존재하지 않습니다\n"); return ret=NULL; } if ( (*root)->data== data){ return ret=*root; } if ((*root)->data > data) ret = search(&((*root)->left), data); else ret = search(&((*root)->right), data); return ret; } node* insert(node** root, int data) { node* ret = (node*)malloc(sizeof(node)); //트리가 비어있으면 그곳에 삽입 if (*root == NULL){ ret->data = data; ret->left = NULL; ret->right = NULL; *root = ret; return ret; } //값이 작을때 왼쪽으로 , 리턴하면서 부모정해주기. if ((*root)->data > data) { ret= insert(&(*root)->left, data); ret->p = *root; } //값이 클때 오른쪽으로, 리턴하면서 부모정해주기. else if ((*root)->data < data) { ret =insert(&(*root)->right, data); ret->p = *root; } return *root; } void del(node** root, int data) { node* del_node = search(root, data); if (del_node == NULL) return; //자식이 하나도 없을 때 if (del_node->left == NULL && del_node->right == NULL) { //지우는 노드가 루트노드일때 if (del_node->p == NULL) { *root = NULL; return; } //자식 노드가 하나도 없을때 부모를 구해서, 해당하는 자식 노드를 삭제해주고 지울노드 해제. node* parent = (node*)malloc(sizeof(node)); parent = del_node->p; if (parent->left == del_node) { parent->left = NULL; } else { parent->right = NULL; } free(del_node); del_node = NULL; } //자식이 둘다 있을 때 else if (del_node->left != NULL && del_node->right != NULL) { node* tmp = (node*)malloc(sizeof(node)); //나보다 큰놈중에서 가장 작은 놈이랑 값을 바꿔줌 tmp = max_min(&(*root)->right); del_node->data = tmp->data; //그리고 그 값을 삭제 del(&del_node->right, tmp->data); } //자식이 하나 있을 때 else { node* tmp = (node*)malloc(sizeof(node)); tmp = del_node->p; //값을 바꿔주고, 자식노드 삭제 if (del_node->left != NULL) { del_node->data = del_node->left->data; del(&del_node->left, del_node->data); } else{ del_node->data = del_node->right->data; del(&del_node->right, del_node->data); } } } void print(node *t) { if (t == NULL) { return; } printf("NODE [%d] > ", t->data); if (t->left != NULL) { printf("LEFT [%d] ", (t->left)->data); } if (t->right != NULL) { printf("RIGHT [%d]", (t->right)->data); } printf("\n"); if (t->left) { print(t->left); } if (t->right) { print(t->right); } } //내 오른쪽에서 가장 왼쪽 구하기 node* max_min(node** root) { node* ret; if ((*root)->left == NULL) { ret = *root; return ret; } ret = max_min(&(*root)->left); return ret; } | cs |
반응형
'잡다한 IT > 자료구조' 카테고리의 다른 글
퀵소트 vs 머지소트 (0) | 2018.05.12 |
---|---|
Sort , Search (0) | 2018.05.07 |
연결리스트를 통한 큐 구현 (0) | 2018.04.24 |
연결리스트를 통한 스택 구현 (0) | 2018.04.24 |
링크드 리스트 구현 (0) | 2018.04.23 |