Advertisement
RedWarden

과제로부터해방된RBT

Nov 17th, 2019
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.63 KB | None | 0 0
  1. 참고!
  2. 아래 파일은 한개의 C파일과 4개의 헤더파일로 구성되어 있음!
  3.  
  4. MAIN.C
  5.  
  6. #include <stdio.h>
  7. #include "node.h"
  8. #include "insertion.h"
  9. #include "rotation.h"
  10. #include "correctTree.h"
  11.  
  12. int main(void)
  13. {
  14. //루트노드
  15. rbnode root;
  16. //삽입버퍼노드
  17. rbnode val;
  18. //NIL 노드
  19. rbnode nil;
  20. int input;
  21.  
  22. //NIL 할당
  23. nil = create_nil();
  24. //첫 루트노드는 NIL
  25. root = nil;
  26.  
  27. int i = 0, size = 0, sk = 0, ch = 0;
  28. printf("Enter the number of input data in RBT\n");
  29. scanf_s("%d", &size);
  30. printf("---------\n");
  31.  
  32. //사이즈만큼 반복하여 노드 생성
  33. while (i < size) {
  34. printf("Enter data in RBT\n");
  35. scanf_s("%d", &input);
  36. printf("---------\n");
  37. printf("Key=%3d\n", input);
  38.  
  39. //노드 할당
  40. val = create_node(input, nil);
  41. //노드 삽입
  42. root = rb_insert(root, val, nil);
  43. printf("---------\n\n");
  44. i++;
  45. }
  46. //메뉴 구성
  47. while (1) {
  48. printf("\n1. Display\t2. Exit\t\t3.Search\n");
  49. printf("Enter your choice:");
  50. scanf_s("%d", &ch);
  51.  
  52. switch (ch) {
  53. case 1:
  54. //display
  55. printf("\n* display RB tree*\n");
  56. printf("----------------------------------------------------------------------\n");
  57. inorder(root, nil);
  58. printf("----------------------------------------------------------------------\n");
  59. break;
  60. case 2:
  61. //exit
  62. free(root);
  63. free(val);
  64. free(nil);
  65. exit(0);
  66. break;
  67. case 3:
  68. //search
  69. printf("Enter the Data value:");
  70. scanf_s("%d", &sk);
  71. if (searchNode(root,nil,sk)) {
  72. printf("the Data %d is found!\n",sk);
  73. }
  74. else {
  75. printf("Sorry, Search Failed..\n");
  76. }
  77. printf("\n");
  78. break;
  79. default:
  80. printf("wrong option!!\n");
  81. break;
  82. }
  83.  
  84. }
  85.  
  86.  
  87. return 0;
  88. }
  89.  
  90.  
  91.  
  92. ---------------------------------------------------------------------------------------------------------
  93. CORRECTTREE.H
  94.  
  95. #pragma once
  96. #include "node.h"
  97. #include "rotation.h"
  98. //정렬 함수 및 검색 함수 헤더(로테이션,노드 의존)
  99. rbnode fix(rbnode root, rbnode input, rbnode nil)
  100. {
  101. rbnode uncle;
  102. while (input->p->color == RED) {
  103. //부모의 색이 빨강색인 경우
  104. if ((input->p) == (input->p->p->left)) {
  105. //
  106. uncle = input->p->p->right;
  107. if (uncle->color == RED) {
  108. input->p->color = BLACK;
  109. uncle->color = BLACK;
  110. input->p->p->color = RED;
  111.  
  112. input = input->p->p;
  113. }
  114. else {
  115. if (input == input->p->right) {
  116. input = input->p;
  117. root = left_rotate(root, input, nil);
  118. }
  119. input->p->color = BLACK;
  120. input->p->p->color = RED;
  121. root = right_rotate(root, input->p->p, nil);
  122. }
  123. }
  124. else {
  125. uncle = input->p->p->left;
  126. if (uncle->color == RED) {
  127. input->p->color = BLACK;
  128. uncle->color = BLACK;
  129. input->p->p->color = RED;
  130.  
  131. input = input->p->p;
  132. }
  133. else {
  134. if (input == input->p->left) {
  135. input = input->p;
  136. root = right_rotate(root, input, nil);
  137. }
  138. input->p->color = BLACK;
  139. input->p->p->color = RED;
  140. root = left_rotate(root, input->p->p, nil);
  141. }
  142. }
  143. }
  144. root->color = BLACK;
  145. //루트 노드를 리턴!
  146. return root;
  147. }
  148. int searchNode(rbnode root,rbnode nil, int sk) {
  149. //검색 실패시 0(false), 성공시 1(true)
  150. if (root->key == sk) {
  151. //검색 성공
  152. return 1;
  153. }
  154. if (root == nil) {
  155. //검색 실패
  156. return 0;
  157. }
  158. //재귀하며 계속 검색
  159. if (sk < root->key) {
  160. return searchNode(root->left, nil, sk);
  161. }
  162. else {
  163. return searchNode(root->right, nil, sk);
  164. }
  165. }
  166.  
  167.  
  168.  
  169.  
  170.  
  171. -------------------------------------------------------------------------------------------
  172.  
  173. INSERTION.H
  174.  
  175. #pragma once
  176. #include "node.h"
  177. #include "correctTree.h"
  178. //트리에 노드삽입함수 관련 정의 헤더(정렬 함수, 노드 의존)
  179. rbnode rb_insert(rbnode root, rbnode input, rbnode nil) {
  180. rbnode tree = nil;
  181. rbnode r = root;
  182.  
  183. while (r != nil) {
  184. tree = r;
  185. if ((input->key) < (r->key))
  186. r = r->left;
  187. else
  188. r = r->right;
  189. }
  190.  
  191. input->p = tree;
  192.  
  193. if (tree == nil)
  194. root = input;
  195. else if ((input->key) < (tree->key))
  196. tree->left = input;
  197. else
  198. tree->right = input;
  199.  
  200. input->left = nil;
  201. input->right = nil;
  202. input->color = RED;
  203. //루트 노드를 받아 다시 리턴!
  204. return fix(root, input, nil);
  205. }
  206.  
  207.  
  208.  
  209.  
  210. ---------------------------------------------------------------------------------------------
  211.  
  212. NODE.H
  213.  
  214. #pragma once
  215. #include <stdlib.h>
  216. #include <stdio.h>
  217.  
  218. enum COLOR { RED, BLACK };
  219. typedef enum COLOR COLOR;
  220. //노드 생성과 노드 출력, 노드 검사 헤더
  221.  
  222.  
  223. struct node
  224. {
  225. int key;
  226. COLOR color;
  227. struct node* left;
  228. struct node* right;
  229. struct node* p;
  230. };
  231.  
  232. typedef struct node NODE;
  233. typedef NODE* rbnode;
  234.  
  235. rbnode create_node(int input, rbnode nil)
  236. {
  237. //노드할당함수
  238. rbnode newNode = (rbnode)malloc(sizeof(NODE));
  239. newNode->key = input;
  240. //노드끝은 항상 NIL로 수렴
  241. newNode->left = nil;
  242. newNode->right = nil;
  243. newNode->p = nil;
  244.  
  245. return newNode;
  246. }
  247.  
  248. rbnode create_nil()
  249. {
  250. //NIL노드할당함수
  251. rbnode nil = (rbnode)malloc(sizeof(NODE));
  252. //키값은 0
  253. nil->key = 0;
  254. //NULL 포인터
  255. nil->left = NULL;
  256. nil->right = NULL;
  257. nil->p = NULL;
  258. //NIL은 검은색으로 처리
  259. nil->color = BLACK;
  260.  
  261. return nil;
  262. }
  263.  
  264. void inorder(rbnode root, rbnode nil)
  265. {
  266. //중위순회를 이용한 출력함수
  267. //LEFT,DRIVE,RIGHT(LDR)
  268. if (root != nil)
  269. {
  270. inorder(root->left, nil);
  271. printf("left child <%2d> - root<%2d> - <%2d> right child \n parent of root :\
  272. %2d , color : %4s\n\n", root->left->key, root->key, root->right->key,
  273. root->p->key, (root->color == RED) ? "red" : "black");
  274. inorder(root->right, nil);
  275. }
  276.  
  277. }
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284. --------------------------------------------------------------------------------------------------------
  285.  
  286. ROTATION.H
  287.  
  288. #pragma once
  289. #include "node.h"
  290. //노드 정렬시 로테이션 함수 정의 헤더(노드 의존)
  291. rbnode left_rotate(rbnode root, rbnode node, rbnode nil) {
  292. //node변수 위치가 가운데로 가게 됨.
  293. rbnode tmp = node->right;
  294. node->right = tmp->left;
  295.  
  296. if (tmp->left != nil)
  297. tmp->left->p = node;
  298.  
  299. tmp->p = node->p;
  300. if (node->p == nil) root = tmp;
  301. else if (node == node->p->left)
  302. node->p->left = tmp;
  303. else
  304. node->p->right = tmp;
  305.  
  306. tmp->left = node;
  307. node->p = tmp;
  308.  
  309. return root;
  310.  
  311. }
  312.  
  313. rbnode right_rotate(rbnode root, rbnode node, rbnode nil) {
  314. rbnode tmp = node->left;
  315. node->left = tmp->right;
  316.  
  317. if (tmp->right != nil)
  318. tmp->right->p = node;
  319.  
  320. tmp->p = node->p;
  321. if (node->p == nil) root = tmp;
  322. else if (node == node->p->right)
  323. node->p->right = tmp;
  324. else
  325. node->p->left = tmp;
  326.  
  327. tmp->right = node;
  328. node->p = tmp;
  329.  
  330. return root;
  331.  
  332. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement