btree.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:10k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * FILE:     btree.c
  3.  * PROGRAM:  RAT
  4.  * AUTHOR:   O.Hodson
  5.  * MODIFIED: C.Perkins
  6.  * 
  7.  * Binary tree implementation - Mostly verbatim from:
  8.  *
  9.  * Introduction to Algorithms by Corman, Leisserson, and Rivest,
  10.  * MIT Press / McGraw Hill, 1990.
  11.  *
  12.  */
  13. #include "config_unix.h"
  14. #include "config_win32.h"
  15. #include "debug.h"
  16. #include "memory.h"
  17. #include "btree.h"
  18. typedef struct s_btree_node {
  19.         uint32_t         key;
  20.         void          *data;
  21.         struct s_btree_node  *parent;
  22.         struct s_btree_node  *left;
  23.         struct s_btree_node  *right;
  24. uint32_t  magic;
  25. } btree_node_t;
  26. struct s_btree {
  27.         btree_node_t   *root;
  28. uint32_t magic;
  29. int count;
  30. };
  31. /*****************************************************************************/
  32. /* Debugging functions...                                                    */
  33. /*****************************************************************************/
  34. #define BTREE_MAGIC      0x10101010
  35. #define BTREE_NODE_MAGIC 0x01010101
  36. static int btree_count;
  37. static void
  38. btree_validate_node(btree_node_t *node, btree_node_t *parent)
  39. {
  40. ASSERT(node->magic  == BTREE_NODE_MAGIC);
  41. ASSERT(node->parent == parent);
  42. btree_count++;
  43. if (node->left != NULL) {
  44. btree_validate_node(node->left, node);
  45. }
  46. if (node->right != NULL) {
  47. btree_validate_node(node->right, node);
  48. }
  49. }
  50. static void
  51. btree_validate(btree_t *t)
  52. {
  53. ASSERT(t->magic == BTREE_MAGIC);
  54. #ifdef DEBUG
  55. btree_count = 0;
  56. if (t->root != NULL) {
  57. btree_validate_node(t->root, NULL);
  58. }
  59. ASSERT(btree_count == t->count);
  60. #endif
  61. }
  62. /*****************************************************************************/
  63. /* Utility functions                                                         */
  64. /*****************************************************************************/
  65. static btree_node_t*
  66. btree_min(btree_node_t *x)
  67. {
  68.         if (x == NULL) {
  69.                 return NULL;
  70.         }
  71.         while(x->left) {
  72.                 x = x->left;
  73.         }
  74.         return x;
  75. }
  76. static btree_node_t*
  77. btree_max(btree_node_t *x)
  78. {
  79.         if (x == NULL) {
  80.                 return NULL;
  81.         }
  82.         while(x->right) {
  83.                 x = x->right;
  84.         }
  85.         return x;
  86. }
  87. static btree_node_t*
  88. btree_successor(btree_node_t *x)
  89. {
  90.         btree_node_t *y;
  91.         if (x->right != NULL) {
  92.                 return btree_min(x->right);
  93.         }
  94.         y = x->parent;
  95.         while (y != NULL && x == y->right) {
  96.                 x = y;
  97.                 y = y->parent;
  98.         }
  99.         return y;
  100. }
  101. static btree_node_t*
  102. btree_search(btree_node_t *x, uint32_t key)
  103. {
  104.         while (x != NULL && key != x->key) {
  105.                 if (key < x->key) {
  106.                         x = x->left;
  107.                 } else {
  108.                         x = x->right;
  109.                 }
  110.         }
  111.         return x; 
  112. }
  113. static void
  114. btree_insert_node(btree_t *tree, btree_node_t *z) {
  115.         btree_node_t *x, *y;
  116. btree_validate(tree);
  117.         y = NULL;
  118.         x = tree->root;
  119.         while (x != NULL) {
  120.                 y = x;
  121.                 ASSERT(z->key != x->key);
  122.                 if (z->key < x->key) {
  123.                         x = x->left;
  124.                 } else {
  125.                         x = x->right;
  126.                 }
  127.         }
  128.         z->parent = y;
  129.         if (y == NULL) {
  130.                 tree->root = z;
  131.         } else if (z->key < y->key) {
  132.                 y->left = z;
  133.         } else {
  134.                 y->right = z;
  135.         }
  136. tree->count++;
  137. btree_validate(tree);
  138. }
  139. static btree_node_t*
  140. btree_delete_node(btree_t *tree, btree_node_t *z)
  141. {
  142.         btree_node_t *x, *y;
  143. btree_validate(tree);
  144.         if (z->left == NULL || z->right == NULL) {
  145.                 y = z;
  146.         } else {
  147.                 y = btree_successor(z);
  148.         }
  149.         if (y->left != NULL) {
  150.                 x = y->left;
  151.         } else {
  152.                 x = y->right;
  153.         }
  154.         if (x != NULL) {
  155.                 x->parent = y->parent;
  156.         }
  157.         if (y->parent == NULL) {
  158.                 tree->root = x;
  159.         } else if (y == y->parent->left) {
  160.                 y->parent->left = x;
  161.         } else {
  162.                 y->parent->right = x;
  163.         }
  164.         z->key  = y->key;
  165.         z->data = y->data;
  166. tree->count--;
  167. btree_validate(tree);
  168.         return y;
  169. }
  170. /*****************************************************************************/
  171. /* Exported functions                                                        */
  172. /*****************************************************************************/
  173. int
  174. btree_create(btree_t **tree)
  175. {
  176.         btree_t *t = (btree_t*)xmalloc(sizeof(btree_t));
  177.         if (t) {
  178. t->count = 0;
  179. t->magic = BTREE_MAGIC;
  180.                 t->root  = NULL;
  181.                 *tree = t;
  182.                 return TRUE;
  183.         }
  184.         return FALSE;
  185. }
  186. int
  187. btree_destroy(btree_t **tree)
  188. {
  189.         btree_t *t = *tree;
  190. btree_validate(t);
  191.         if (t->root != NULL) {
  192.                 debug_msg("Tree not empty - cannot destroyn");
  193.                 return FALSE;
  194.         }
  195.         xfree(t);
  196.         *tree = NULL;
  197.         return TRUE;
  198. }
  199. int
  200. btree_find(btree_t *tree, uint32_t key, void **d)
  201. {
  202.         btree_node_t *x;
  203. btree_validate(tree);
  204.         x = btree_search(tree->root, key);
  205.         if (x != NULL) {
  206.                 *d = x->data;
  207.                 return TRUE;
  208.         }
  209.         return FALSE;
  210. }
  211. int 
  212. btree_add(btree_t *tree, uint32_t key, void *data)
  213. {
  214.         btree_node_t *x;
  215. btree_validate(tree);
  216.         x = btree_search(tree->root, key);
  217.         if (x != NULL) {
  218.                 debug_msg("Item already exists - key %uln", key);
  219.                 return FALSE;
  220.         }
  221.         x = (btree_node_t *)xmalloc(sizeof(btree_node_t));
  222.         x->key    = key;
  223.         x->data   = data;
  224.         x->parent = NULL;
  225. x->left   = NULL;
  226. x->right  = NULL;
  227. x->magic  = BTREE_NODE_MAGIC;
  228.         btree_insert_node(tree, x);
  229.         return TRUE;
  230. }
  231. int
  232. btree_remove(btree_t *tree, uint32_t key, void **data)
  233. {
  234.         btree_node_t *x;
  235. btree_validate(tree);
  236.         x = btree_search(tree->root, key);
  237.         if (x == NULL) {
  238.                 debug_msg("Item not on tree - key %uln", key);
  239.                 *data = NULL;
  240.                 return FALSE;
  241.         }
  242.         /* Note value that gets freed is not necessarily the the same
  243.          * as node that gets removed from tree since there is an
  244.          * optimization to avoid pointer updates in tree which means
  245.          * sometimes we just copy key and data from one node to
  246.          * another.  
  247.          */
  248.         *data = x->data;
  249.         x = btree_delete_node(tree, x);
  250.         xfree(x);
  251.         return TRUE;
  252. }
  253. int 
  254. btree_get_min_key(btree_t *tree, uint32_t *key)
  255. {
  256.         btree_node_t *x;
  257. btree_validate(tree);
  258.         if (tree->root == NULL) {
  259.                 return FALSE;
  260.         }
  261.         x = btree_min(tree->root);
  262.         if (x == NULL) {
  263.                 return FALSE;
  264.         }
  265.         
  266.         *key = x->key;
  267.         return TRUE;
  268. }
  269. int 
  270. btree_get_max_key(btree_t *tree, uint32_t *key)
  271. {
  272.         btree_node_t *x;
  273. btree_validate(tree);
  274.         if (tree->root == NULL) {
  275.                 return FALSE;
  276.         }
  277.         x = btree_max(tree->root);
  278.         if (x == NULL) {
  279.                 return FALSE;
  280.         }
  281.         
  282.         *key = x->key;
  283.         return TRUE;
  284. }
  285. int
  286. btree_get_next_key(btree_t *tree, uint32_t cur_key, uint32_t *next_key)
  287. {
  288.         btree_node_t *x;
  289. btree_validate(tree);
  290.         x = btree_search(tree->root, cur_key);
  291.         if (x == NULL) {
  292.                 return FALSE;
  293.         }
  294.         
  295.         x = btree_successor(x);
  296.         if (x == NULL) {
  297.                 return FALSE;
  298.         }
  299.         
  300.         *next_key = x->key;
  301.         return TRUE;
  302. }
  303. /*****************************************************************************/
  304. /* Test code                                                                 */
  305. /*****************************************************************************/
  306. #ifdef TEST_BTREE
  307. static int
  308. btree_depth(btree_node_t *x)
  309. {
  310.         int l, r;
  311.         if (x == NULL) {
  312.                 return 0;
  313.         }
  314.         l = btree_depth(x->left);
  315.         r = btree_depth(x->right);
  316.         if (l > r) {
  317.                 return l + 1;
  318.         } else {
  319.                 return r + 1;
  320.         }
  321. }
  322. #include <curses.h>
  323. static void
  324. btree_dump_node(btree_node_t *x, int depth, int c, int w)
  325. {
  326.         if (x == NULL) {
  327.                 return;
  328.         }
  329.         
  330.         move(depth * 2, c);
  331.         printw("%lu", x->key);
  332.         refresh();
  333.         btree_dump_node(x->left,  depth + 1, c - w/2, w/2);
  334.         btree_dump_node(x->right, depth + 1, c + w/2, w/2);
  335.         return;
  336. }
  337. static void
  338. btree_dump(btree_t *b)
  339. {
  340.         initscr();
  341.         btree_dump_node(b->root, 0, 40, 48);
  342.         refresh();
  343.         endwin();
  344. }
  345. #include "stdlib.h"
  346. int 
  347. main()
  348. {
  349.         btree_t *b;
  350.         uint32_t i, *x;
  351.         uint32_t v[] = {15, 5, 16, 3, 12, 20, 10, 13, 18, 23, 6, 7}; 
  352.         uint32_t nv = sizeof(v) / sizeof(v[0]);
  353.         btree_create(&b);
  354.         for(i = 0; i < nv; i++) {
  355.                 x = (uint32_t*)xmalloc(sizeof(uint32_t));
  356.                 *x = (uint32_t)random();
  357.                 if (btree_add(b, v[i], (void*)x) != TRUE) {
  358.                         printf("Fail Add %lu %lun", v[i], *x);
  359.                 }
  360.         }
  361.     
  362.         printf("depth %dn", btree_depth(b->root));
  363.         btree_dump(b);
  364.         sleep(3);
  365.         btree_remove(b, 5, (void*)&x);
  366.         btree_dump(b);
  367.         sleep(3);
  368.         btree_remove(b, 16, (void*)&x);
  369.         btree_dump(b);
  370.         sleep(3);
  371.         btree_remove(b, 13, (void*)&x);
  372.         btree_dump(b);
  373.         while (btree_get_root_key(b, &i)) {
  374.                 if (btree_remove(b, i, (void*)&x) == FALSE) {
  375.                         fprintf(stderr, "Failed to remove %lun", i);
  376.                 }
  377.                 btree_dump(b);
  378.                 sleep(1); 
  379.         }
  380.         if (btree_destroy(&b) == FALSE) {
  381.                 printf("Failed to destroy n");
  382.         }
  383.                 
  384.         return 0;
  385. }
  386. #endif /* TEST_BTREE*/