btree.c
资源名称:NETVIDEO.rar [点击查看]
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:10k
源码类别:
流媒体/Mpeg4/MP4
开发平台:
Visual C++
- /*
- * FILE: btree.c
- * PROGRAM: RAT
- * AUTHOR: O.Hodson
- * MODIFIED: C.Perkins
- *
- * Binary tree implementation - Mostly verbatim from:
- *
- * Introduction to Algorithms by Corman, Leisserson, and Rivest,
- * MIT Press / McGraw Hill, 1990.
- *
- */
- #include "config_unix.h"
- #include "config_win32.h"
- #include "debug.h"
- #include "memory.h"
- #include "btree.h"
- typedef struct s_btree_node {
- uint32_t key;
- void *data;
- struct s_btree_node *parent;
- struct s_btree_node *left;
- struct s_btree_node *right;
- uint32_t magic;
- } btree_node_t;
- struct s_btree {
- btree_node_t *root;
- uint32_t magic;
- int count;
- };
- /*****************************************************************************/
- /* Debugging functions... */
- /*****************************************************************************/
- #define BTREE_MAGIC 0x10101010
- #define BTREE_NODE_MAGIC 0x01010101
- static int btree_count;
- static void
- btree_validate_node(btree_node_t *node, btree_node_t *parent)
- {
- ASSERT(node->magic == BTREE_NODE_MAGIC);
- ASSERT(node->parent == parent);
- btree_count++;
- if (node->left != NULL) {
- btree_validate_node(node->left, node);
- }
- if (node->right != NULL) {
- btree_validate_node(node->right, node);
- }
- }
- static void
- btree_validate(btree_t *t)
- {
- ASSERT(t->magic == BTREE_MAGIC);
- #ifdef DEBUG
- btree_count = 0;
- if (t->root != NULL) {
- btree_validate_node(t->root, NULL);
- }
- ASSERT(btree_count == t->count);
- #endif
- }
- /*****************************************************************************/
- /* Utility functions */
- /*****************************************************************************/
- static btree_node_t*
- btree_min(btree_node_t *x)
- {
- if (x == NULL) {
- return NULL;
- }
- while(x->left) {
- x = x->left;
- }
- return x;
- }
- static btree_node_t*
- btree_max(btree_node_t *x)
- {
- if (x == NULL) {
- return NULL;
- }
- while(x->right) {
- x = x->right;
- }
- return x;
- }
- static btree_node_t*
- btree_successor(btree_node_t *x)
- {
- btree_node_t *y;
- if (x->right != NULL) {
- return btree_min(x->right);
- }
- y = x->parent;
- while (y != NULL && x == y->right) {
- x = y;
- y = y->parent;
- }
- return y;
- }
- static btree_node_t*
- btree_search(btree_node_t *x, uint32_t key)
- {
- while (x != NULL && key != x->key) {
- if (key < x->key) {
- x = x->left;
- } else {
- x = x->right;
- }
- }
- return x;
- }
- static void
- btree_insert_node(btree_t *tree, btree_node_t *z) {
- btree_node_t *x, *y;
- btree_validate(tree);
- y = NULL;
- x = tree->root;
- while (x != NULL) {
- y = x;
- ASSERT(z->key != x->key);
- if (z->key < x->key) {
- x = x->left;
- } else {
- x = x->right;
- }
- }
- z->parent = y;
- if (y == NULL) {
- tree->root = z;
- } else if (z->key < y->key) {
- y->left = z;
- } else {
- y->right = z;
- }
- tree->count++;
- btree_validate(tree);
- }
- static btree_node_t*
- btree_delete_node(btree_t *tree, btree_node_t *z)
- {
- btree_node_t *x, *y;
- btree_validate(tree);
- if (z->left == NULL || z->right == NULL) {
- y = z;
- } else {
- y = btree_successor(z);
- }
- if (y->left != NULL) {
- x = y->left;
- } else {
- x = y->right;
- }
- if (x != NULL) {
- x->parent = y->parent;
- }
- if (y->parent == NULL) {
- tree->root = x;
- } else if (y == y->parent->left) {
- y->parent->left = x;
- } else {
- y->parent->right = x;
- }
- z->key = y->key;
- z->data = y->data;
- tree->count--;
- btree_validate(tree);
- return y;
- }
- /*****************************************************************************/
- /* Exported functions */
- /*****************************************************************************/
- int
- btree_create(btree_t **tree)
- {
- btree_t *t = (btree_t*)xmalloc(sizeof(btree_t));
- if (t) {
- t->count = 0;
- t->magic = BTREE_MAGIC;
- t->root = NULL;
- *tree = t;
- return TRUE;
- }
- return FALSE;
- }
- int
- btree_destroy(btree_t **tree)
- {
- btree_t *t = *tree;
- btree_validate(t);
- if (t->root != NULL) {
- debug_msg("Tree not empty - cannot destroyn");
- return FALSE;
- }
- xfree(t);
- *tree = NULL;
- return TRUE;
- }
- int
- btree_find(btree_t *tree, uint32_t key, void **d)
- {
- btree_node_t *x;
- btree_validate(tree);
- x = btree_search(tree->root, key);
- if (x != NULL) {
- *d = x->data;
- return TRUE;
- }
- return FALSE;
- }
- int
- btree_add(btree_t *tree, uint32_t key, void *data)
- {
- btree_node_t *x;
- btree_validate(tree);
- x = btree_search(tree->root, key);
- if (x != NULL) {
- debug_msg("Item already exists - key %uln", key);
- return FALSE;
- }
- x = (btree_node_t *)xmalloc(sizeof(btree_node_t));
- x->key = key;
- x->data = data;
- x->parent = NULL;
- x->left = NULL;
- x->right = NULL;
- x->magic = BTREE_NODE_MAGIC;
- btree_insert_node(tree, x);
- return TRUE;
- }
- int
- btree_remove(btree_t *tree, uint32_t key, void **data)
- {
- btree_node_t *x;
- btree_validate(tree);
- x = btree_search(tree->root, key);
- if (x == NULL) {
- debug_msg("Item not on tree - key %uln", key);
- *data = NULL;
- return FALSE;
- }
- /* Note value that gets freed is not necessarily the the same
- * as node that gets removed from tree since there is an
- * optimization to avoid pointer updates in tree which means
- * sometimes we just copy key and data from one node to
- * another.
- */
- *data = x->data;
- x = btree_delete_node(tree, x);
- xfree(x);
- return TRUE;
- }
- int
- btree_get_min_key(btree_t *tree, uint32_t *key)
- {
- btree_node_t *x;
- btree_validate(tree);
- if (tree->root == NULL) {
- return FALSE;
- }
- x = btree_min(tree->root);
- if (x == NULL) {
- return FALSE;
- }
- *key = x->key;
- return TRUE;
- }
- int
- btree_get_max_key(btree_t *tree, uint32_t *key)
- {
- btree_node_t *x;
- btree_validate(tree);
- if (tree->root == NULL) {
- return FALSE;
- }
- x = btree_max(tree->root);
- if (x == NULL) {
- return FALSE;
- }
- *key = x->key;
- return TRUE;
- }
- int
- btree_get_next_key(btree_t *tree, uint32_t cur_key, uint32_t *next_key)
- {
- btree_node_t *x;
- btree_validate(tree);
- x = btree_search(tree->root, cur_key);
- if (x == NULL) {
- return FALSE;
- }
- x = btree_successor(x);
- if (x == NULL) {
- return FALSE;
- }
- *next_key = x->key;
- return TRUE;
- }
- /*****************************************************************************/
- /* Test code */
- /*****************************************************************************/
- #ifdef TEST_BTREE
- static int
- btree_depth(btree_node_t *x)
- {
- int l, r;
- if (x == NULL) {
- return 0;
- }
- l = btree_depth(x->left);
- r = btree_depth(x->right);
- if (l > r) {
- return l + 1;
- } else {
- return r + 1;
- }
- }
- #include <curses.h>
- static void
- btree_dump_node(btree_node_t *x, int depth, int c, int w)
- {
- if (x == NULL) {
- return;
- }
- move(depth * 2, c);
- printw("%lu", x->key);
- refresh();
- btree_dump_node(x->left, depth + 1, c - w/2, w/2);
- btree_dump_node(x->right, depth + 1, c + w/2, w/2);
- return;
- }
- static void
- btree_dump(btree_t *b)
- {
- initscr();
- btree_dump_node(b->root, 0, 40, 48);
- refresh();
- endwin();
- }
- #include "stdlib.h"
- int
- main()
- {
- btree_t *b;
- uint32_t i, *x;
- uint32_t v[] = {15, 5, 16, 3, 12, 20, 10, 13, 18, 23, 6, 7};
- uint32_t nv = sizeof(v) / sizeof(v[0]);
- btree_create(&b);
- for(i = 0; i < nv; i++) {
- x = (uint32_t*)xmalloc(sizeof(uint32_t));
- *x = (uint32_t)random();
- if (btree_add(b, v[i], (void*)x) != TRUE) {
- printf("Fail Add %lu %lun", v[i], *x);
- }
- }
- printf("depth %dn", btree_depth(b->root));
- btree_dump(b);
- sleep(3);
- btree_remove(b, 5, (void*)&x);
- btree_dump(b);
- sleep(3);
- btree_remove(b, 16, (void*)&x);
- btree_dump(b);
- sleep(3);
- btree_remove(b, 13, (void*)&x);
- btree_dump(b);
- while (btree_get_root_key(b, &i)) {
- if (btree_remove(b, i, (void*)&x) == FALSE) {
- fprintf(stderr, "Failed to remove %lun", i);
- }
- btree_dump(b);
- sleep(1);
- }
- if (btree_destroy(&b) == FALSE) {
- printf("Failed to destroy n");
- }
- return 0;
- }
- #endif /* TEST_BTREE*/