Data Structure - Red Black Tree (C)

ゝ一纸荒年。 2023-01-20 10:58 80阅读 0赞

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net

  1. /*
  2. * Fatal.h - by FreeMan
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #define Error( Str ) FatalError( Str )
  7. #define FatalError( Str ) fprintf( stderr, "%s\n", Str ), exit( 1 )
  8. /*
  9. * RedBlackTree.h - by FreeMan
  10. */
  11. typedef int ElementType;
  12. #define NegInfinity (-10000)
  13. #ifndef _RedBlackTree_H_
  14. #define _RedBlackTree_H_
  15. struct RedBlackNode;
  16. typedef struct RedBlackNode *Position;
  17. typedef struct RedBlackNode *RedBlackTree;
  18. RedBlackTree MakeRedBlackTreeEmpty(RedBlackTree T);
  19. Position FindInRedBlackTree(ElementType X, RedBlackTree T);
  20. Position FindMinInRedBlackTree(RedBlackTree T);
  21. Position FindMaxInRedBlackTree(RedBlackTree T);
  22. RedBlackTree InitializeRedBlackTree(void);
  23. RedBlackTree InsertInRedBlackTree(ElementType X, RedBlackTree T);
  24. RedBlackTree RemoveInRedBlackTree(ElementType X, RedBlackTree T);
  25. ElementType RetrieveInRedBlackTree(Position P);
  26. void PrintRedBlackTree(RedBlackTree T);
  27. #endif
  28. /*
  29. * RedBlackTree.c - by FreeMan
  30. */
  31. #include "RedBlackTree.h"
  32. #include "Fatal.h"
  33. #include <stdlib.h>
  34. typedef enum ColorType { Red, Black } ColorType;
  35. struct RedBlackNode
  36. {
  37. ElementType Element;
  38. RedBlackTree Left;
  39. RedBlackTree Right;
  40. ColorType Color;
  41. };
  42. /* Needs initialization */
  43. static Position NullNode = NULL;
  44. RedBlackTree InitializeRedBlackTree(void)
  45. {
  46. RedBlackTree T;
  47. if (NullNode == NULL)
  48. {
  49. NullNode = malloc(sizeof(struct RedBlackNode));
  50. if (NullNode == NULL)
  51. {
  52. FatalError("Out of memory!!");
  53. }
  54. NullNode->Left = NullNode->Right = NullNode;
  55. NullNode->Color = Black;
  56. NullNode->Element = 12345;
  57. }
  58. /* Create the header node */
  59. T = malloc(sizeof(struct RedBlackNode));
  60. if (T == NULL)
  61. {
  62. FatalError("Out of memory!!");
  63. }
  64. T->Element = NegInfinity;
  65. T->Left = T->Right = NullNode;
  66. T->Color = Black;
  67. return T;
  68. }
  69. void Output(ElementType Element)
  70. {
  71. printf("%d\n", Element);
  72. }
  73. /* Print the tree, watch out for NullNode, and skip header */
  74. static void DoPrint(RedBlackTree T)
  75. {
  76. if (T != NullNode)
  77. {
  78. DoPrint(T->Left);
  79. Output(T->Element);
  80. DoPrint(T->Right);
  81. }
  82. }
  83. void PrintRedBlackTree(RedBlackTree T)
  84. {
  85. DoPrint(T->Right);
  86. }
  87. static RedBlackTree MakeEmptyRec(RedBlackTree T)
  88. {
  89. if (T != NullNode)
  90. {
  91. MakeEmptyRec(T->Left);
  92. MakeEmptyRec(T->Right);
  93. free(T);
  94. }
  95. return NullNode;
  96. }
  97. RedBlackTree MakeRedBlackTreeEmpty(RedBlackTree T)
  98. {
  99. T->Right = MakeEmptyRec(T->Right);
  100. return T;
  101. }
  102. Position FindInRedBlackTree(ElementType X, RedBlackTree T)
  103. {
  104. if (T == NullNode)
  105. {
  106. return NullNode;
  107. }
  108. if (X < T->Element)
  109. {
  110. return FindInRedBlackTree(X, T->Left);
  111. }
  112. else if (X > T->Element)
  113. {
  114. return FindInRedBlackTree(X, T->Right);
  115. }
  116. else
  117. {
  118. return T;
  119. }
  120. }
  121. Position FindMinInRedBlackTree(RedBlackTree T)
  122. {
  123. T = T->Right;
  124. while (T->Left != NullNode)
  125. {
  126. T = T->Left;
  127. }
  128. return T;
  129. }
  130. Position FindMaxInRedBlackTree(RedBlackTree T)
  131. {
  132. while (T->Right != NullNode)
  133. {
  134. T = T->Right;
  135. }
  136. return T;
  137. }
  138. /*
  139. * This function can be called only if K2 has a left child.
  140. * Perform a rotate between a node (K2) and its left child.
  141. * Update heights, then return new root.
  142. */
  143. static Position SingleRotateWithLeft(Position K2)
  144. {
  145. Position K1;
  146. K1 = K2->Left;
  147. K2->Left = K1->Right;
  148. K1->Right = K2;
  149. return K1; /* New root */
  150. }
  151. /*
  152. * This function can be called only if K1 has a right child.
  153. * Perform a rotate between a node (K1) and its right child.
  154. * Update heights, then return new root.
  155. */
  156. static Position SingleRotateWithRight(Position K1)
  157. {
  158. Position K2;
  159. K2 = K1->Right;
  160. K1->Right = K2->Left;
  161. K2->Left = K1;
  162. return K2; /* New root */
  163. }
  164. /*
  165. * Perform a rotation at node X (whose parent is passed as a parameter).
  166. * The child is deduced by examining Item.
  167. */
  168. static Position Rotate(ElementType Item, Position Parent)
  169. {
  170. if (Item < Parent->Element)
  171. {
  172. return Parent->Left = Item < Parent->Left->Element ?
  173. SingleRotateWithLeft(Parent->Left) :
  174. SingleRotateWithRight(Parent->Left);
  175. }
  176. else
  177. {
  178. return Parent->Right = Item < Parent->Right->Element ?
  179. SingleRotateWithLeft(Parent->Right) :
  180. SingleRotateWithRight(Parent->Right);
  181. }
  182. }
  183. static Position X, P, GP, GGP;
  184. static void HandleReorient(ElementType Item, RedBlackTree T)
  185. {
  186. X->Color = Red; /* Do the color flip */
  187. X->Left->Color = Black;
  188. X->Right->Color = Black;
  189. if (P->Color == Red) /* Have to rotate */
  190. {
  191. GP->Color = Red;
  192. if ((Item < GP->Element) != (Item < P->Element))
  193. {
  194. P = Rotate(Item, GP); /* Start double rotate */
  195. }
  196. X = Rotate(Item, GGP);
  197. X->Color = Black;
  198. }
  199. T->Right->Color = Black; /* Make root black */
  200. }
  201. RedBlackTree InsertInRedBlackTree(ElementType Item, RedBlackTree T)
  202. {
  203. X = P = GP = T;
  204. NullNode->Element = Item;
  205. while (X->Element != Item) /* Descend down the tree */
  206. {
  207. GGP = GP; GP = P; P = X;
  208. if (Item < X->Element)
  209. {
  210. X = X->Left;
  211. }
  212. else
  213. {
  214. X = X->Right;
  215. }
  216. if (X->Left->Color == Red && X->Right->Color == Red)
  217. {
  218. HandleReorient(Item, T);
  219. }
  220. }
  221. if (X != NullNode)
  222. {
  223. return NullNode; /* Duplicate */
  224. }
  225. X = malloc(sizeof(struct RedBlackNode));
  226. if (X == NULL)
  227. {
  228. FatalError("Out of memory!!");
  229. }
  230. X->Element = Item;
  231. X->Left = X->Right = NullNode;
  232. if (Item < P->Element) /* Attach to its parent */
  233. {
  234. P->Left = X;
  235. }
  236. else
  237. {
  238. P->Right = X;
  239. }
  240. HandleReorient(Item, T); /* Color it red; maybe rotate */
  241. return T;
  242. }
  243. RedBlackTree RemoveInRedBlackTree(ElementType Item, RedBlackTree T)
  244. {
  245. printf("Remove is unimplemented\n");
  246. if (Item)
  247. {
  248. return T;
  249. }
  250. return T;
  251. }
  252. ElementType RetrieveInRedBlackTree(Position P)
  253. {
  254. return P->Element;
  255. }
  256. /*
  257. * RedBlackTreeTest.c - by FreeMan
  258. */
  259. #include "RedBlackTree.h"
  260. #include <stdio.h>
  261. #define N 800
  262. main()
  263. {
  264. RedBlackTree T;
  265. Position P;
  266. int i;
  267. int j = 0;
  268. T = InitializeRedBlackTree();
  269. T = MakeRedBlackTreeEmpty(T);
  270. for (i = 0; i < N; i++, j = (j + 7) % N)
  271. {
  272. T = InsertInRedBlackTree(j, T);
  273. }
  274. printf("Inserts are complete\n");
  275. for (i = 0; i < N; i++)
  276. {
  277. if ((P = FindInRedBlackTree(i, T)) == NULL || RetrieveInRedBlackTree(P) != i)
  278. {
  279. printf("Error at %d\n", i);
  280. }
  281. }
  282. printf("Min is %d, Max is %d\n",
  283. RetrieveInRedBlackTree(FindMinInRedBlackTree(T)),
  284. RetrieveInRedBlackTree(FindMaxInRedBlackTree(T)));
  285. return 0;
  286. }
  287. // Output:
  288. /*
  289. Inserts are complete
  290. Min is 0, Max is 799
  291. */

发表评论

表情:
评论列表 (有 0 条评论,80人围观)

还没有评论,来说两句吧...

相关阅读