C红黑树统计英文单词数量
来源:互联网 发布:泰豪软件 编辑:程序博客网 时间:2024/05/01 22:09
#include <stdio.h>#include <stdlib.h>#include <string.h>#define SUCCESS 0#define ERROR -1#define RB_DEFAULT_VALUE 0#define rb_keycmp strcmp#define rb_keydup strdup//to do: 中序和后序非递归遍历,求树的深度,typedef enum { BLACK, RED} rb_color;typedef char* rb_key;typedef size_t rb_value;typedef struct rb_node { rb_color color; struct rb_node *p; struct rb_node *left; struct rb_node *right; rb_key key; rb_value value;} rb_node;typedef struct rbtree { rb_node *root; rb_node *nil; size_t size;} rbtree;typedef struct { rb_key key; rb_value value;} key_value;rb_node *rb_create_node(void) ;//堆上新建结点void *rb_free_node(rb_node *nd) ;//清除结点nd.rbtree *rb_create_tree(void) ;//堆上新建树void rb_free_tree(rbtree *tr) ;//清除树trrb_node *rb_search(rbtree *tr, rb_key z) ;//根据key查找结点,找到返回指针,找不到则返回NULLvoid rb_insert(rbtree *tr, rb_node *z) ;//将z结点插入树int rb_update(rbtree *tr, rb_key key, rb_value value) ; //用value更新key结点的值,找不到结点则返回异常值-1;void rb_delete(rbtree *tr, rb_node *z) ; //删除z结点.rb_node *rb_minimum(rbtree *tr, rb_node* x) ; //tr树x子树的最小结点rb_node *rb_maximum(rbtree *tr, rb_node* x) ; //tr树x子树的最大结点int rb_force_update(rbtree *tr, rb_key key, rb_value value) ;//用value更新或强制建立key结点的值,找不到结点则新建结点再更新;rb_node *rb_force_search(rbtree *tr, rb_key key) ;//根据key强制返回结点(找不到就在堆上新建结点key再返回)key_value *rb_flatten(rbtree *tr) ;//抽取树的键值,按前序遍历的方式将树"扁平化"void rb_graph(rbtree *tr, rb_node *x, char *prefix) ; //打印红黑树的直观图形static void print_by_key_asce(rbtree *tr, rb_node *nd) ; //按key升序遍历打印tr从nd开始的所有键值static void print_by_value_desc(rbtree *tr) ; //按value降序打印所有键值static void test_leak(void); //测试内存泄露static void _rb_free_tree(rbtree *tr, rb_node *nd) ;//辅助函数static void left_rotate(rbtree *tr, rb_node *x) ;//辅助函数static void right_rotate(rbtree *tr, rb_node *x) ;//辅助函数static void rb_transplant(rbtree *tr, rb_node *u, rb_node *v) ;//辅助函数static void rb_insert_fixup(rbtree *tr, rb_node *z) ;//辅助函数static void rb_delete_fixup(rbtree *tr, rb_node *x) ;//辅助函数static int rb_cmp(const void *a, const void *b) ;//用于qsort的辅助函数int main(void) { rbtree *tr = rb_create_tree(); char wd[100]; rb_node *nd; while (scanf("%s\n", wd) == 1) { nd = rb_force_search(tr, wd); nd->value += 1; } print_by_value_desc(tr); nd=tr->root; printf("root is %s\n",nd->key); while (nd!=tr->nil) { rb_delete(tr, nd); nd=tr->root; } printf("after all deleted, tree is like:\n"); print_by_value_desc(tr); rb_free_tree(tr); return SUCCESS;}static void test_leak(void) { int i; rb_node *nd; rbtree *tr = rb_create_tree(); char *keys[]= {"ab","c","de","c","ab","e","c","ee","e"}; for (i=0; i<9; i++) { nd = rb_force_search(tr, keys[i]); nd->value += 1; } print_by_value_desc(tr); rb_free_tree(tr);}rb_node *rb_create_node(void) { rb_node *nd = (rb_node *) malloc(sizeof(rb_node)); if (nd == NULL) return NULL; nd->color = BLACK; nd->p = NULL; nd->left = NULL; nd->right = NULL; nd->key = NULL; nd->value = RB_DEFAULT_VALUE; return nd;}void *rb_free_node(rb_node *nd) { free(nd->key); free(nd); return SUCCESS;}rbtree *rb_create_tree(void) { rbtree *tr = (rbtree *) malloc(sizeof(rbtree)); if (tr == NULL) return NULL; rb_node *nil = rb_create_node(); if (nil == NULL) return NULL; tr->nil = nil; tr->root = nil; tr->size = 0; return tr;}static void _rb_free_tree(rbtree *tr, rb_node *nd) { if (nd != tr->nil) { _rb_free_tree(tr, nd->left); _rb_free_tree(tr, nd->right); free(nd->key); free(nd); }}void rb_free_tree(rbtree *tr) { _rb_free_tree(tr, tr->root); free(tr->nil); free(tr);}static void left_rotate(rbtree *tr, rb_node *x) { rb_node *y = x->right; x->right = y->left; if (y->left != tr->nil) y->left->p = x; y->p = x->p; if (x == tr->root) tr->root = y; else if ( x == x->p->left) x->p->left = y; else x->p->right = y; y->left = x; x->p = y;}static void right_rotate(rbtree *tr, rb_node *x) { rb_node *y = x->left; x->left = y->right; if (y->right != tr->nil) y->right->p = x; y->p = x->p; if (x == tr->root) tr->root = y; else if ( x == x->p->right ) x->p->right = y; else x->p->left = y; y->right = x; x->p = y;}rb_node *rb_search(rbtree *tr, rb_key key) { rb_node *x = tr->root; int r; while (x != tr->nil) { r = rb_keycmp(key, x->key); if (r == 0) return x; else if (r < 0) x = x->left; else x = x->right; } return NULL;}void rb_insert(rbtree *tr, rb_node *z) { rb_node *y = tr->nil; rb_node *x = tr->root; while (x != tr->nil) { y = x; if (rb_keycmp(z->key, x->key) < 0) x = x->left; else x = x->right; } z->p = y; if (y == tr->nil) tr->root = z; else if (rb_keycmp(z->key, y->key) < 0) y->left = z; else y->right = z; z->left = tr->nil; z->right = tr->nil; z->color = RED; rb_insert_fixup(tr, z); tr->size++;}static void rb_insert_fixup(rbtree *tr, rb_node *z) { rb_node *y; while (z->p->color == RED) { if (z->p == z->p->p->left) { y = z->p->p->right; if (y->color == RED) { z->p->color = BLACK; y->color = BLACK; z->p->p->color = RED; z = z->p->p; } else { if (z == z->p->right) { z = z->p; left_rotate(tr, z); } z->p->color = BLACK; z->p->p->color = RED; right_rotate(tr, z->p->p); } } else { y = z->p->p->left; if (y->color == RED) { z->p->color = BLACK; y->color = BLACK; z->p->p->color = RED; z = z->p->p; } else { if (z == z->p->left) { z = z->p; right_rotate(tr, z); } z->p->color = BLACK; z->p->p->color = RED; left_rotate(tr, z->p->p); } } } tr->root->color = BLACK;}rb_node *rb_force_search(rbtree *tr, rb_key key) { rb_node *y = tr->nil; rb_node *x = tr->root; int r; while (x != tr->nil) { r = rb_keycmp(key, x->key); if (r == 0) return x; y = x; if (r < 0) x = x->left; else x = x->right; } rb_node *z = rb_create_node(); rb_node *original_z = z; if (z == NULL) return NULL; if ((z->key = rb_keydup(key)) == NULL) return NULL; z->p = y; if (y == tr->nil) tr->root = z; else if (rb_keycmp(z->key, y->key) < 0) y->left = z; else y->right = z; z->left = tr->nil; z->right = tr->nil; z->color = RED; rb_insert_fixup(tr, z); tr->size++; return original_z;}int rb_update(rbtree *tr, rb_key key, rb_value value) { rb_node* nd = rb_search(tr, key); if (nd == NULL) return ERROR; nd->value = value; return SUCCESS;}int rb_force_update(rbtree *tr, rb_key key, rb_value value) { rb_node* nd = rb_force_search(tr, key); if (nd == NULL) return ERROR; nd->value = value; return SUCCESS;}static void rb_transplant(rbtree *tr, rb_node *u, rb_node *v) { if (u->p == tr->nil) tr->root = v; else if (u == u->p->left) u->p->left = v; else u->p->right = v; v->p = u->p;}rb_node *rb_minimum(rbtree *tr, rb_node* x) { while (x->left != tr->nil) x = x->left; return x;}rb_node *rb_maximum(rbtree *tr, rb_node* x) { while (x->right != tr->nil) x = x->right; return x;}void rb_delete(rbtree *tr, rb_node *z) { rb_node *y = z; rb_color y_original_color = y->color; rb_node *x; if (z->left == tr->nil) { x = z->right; rb_transplant(tr, z, z->right); } else if (z->right == tr->nil) { x = z->left; rb_transplant(tr, z, z->left); } else { y = rb_minimum(tr, z->right); y_original_color = y->color; x = y->right; if (y->p == z) x->p = y; else { rb_transplant(tr, y, y->right); y->right = z->right; y->right->p = y; } rb_transplant(tr, z, y); y->left = z->left; y->left->p = y; y->color = z->color; } if (y_original_color == BLACK) rb_delete_fixup(tr, x); rb_free_node(z); tr->size--;}static void rb_delete_fixup(rbtree *tr, rb_node *x) { while (x != tr->root && x->color == BLACK) { rb_node *w; if (x == x->p->left) { w = x->p->right; if (w->color == RED) { w->color = BLACK; x->p->color = RED; left_rotate(tr, x->p); w = x->p->right; } if (w->left->color == BLACK && w->right->color == BLACK) { w->color = RED; x = x->p; } else { if (w->right->color == BLACK) { w->left->color = BLACK; w->color = RED; right_rotate(tr, w); w = x->p->right; } w->color = x->p->color; w->p->color = BLACK; w->right->color = BLACK; left_rotate(tr, x->p); x = tr->root; } } else { w = x->p->left; if (w->color == RED) { w->color = BLACK; x->p->color = RED; right_rotate(tr, x->p); w = x->p->left; } if (w->right->color == BLACK && w->left->color == BLACK) { w->color = RED; x = x->p; } else { if (w->left->color == BLACK) { w->right->color = BLACK; w->color = RED; left_rotate(tr, w); w = x->p->left; } w->color = x->p->color; w->p->color = BLACK; w->left->color = BLACK; right_rotate(tr, x->p); x = tr->root; } } } x->color = BLACK;}#define LEF "└───"#define RIG "┌───"#define IND1 " "#define IND2 "│ "void rb_graph(rbtree *tr, rb_node *x, char *prefix) { if (x != tr->nil) { rb_node *p = x->p; char *last_prefix; if (p != tr->nil) { rb_node *print_by_key_asce = p->p; if (p->left == x) last_prefix = LEF; else last_prefix = RIG; if (print_by_key_asce != tr->nil) { if ((print_by_key_asce->left == p) == (p->left == x)) prefix = strcat(prefix, IND1); else prefix = strcat(prefix, IND2); } } rb_graph(tr, x->right, prefix); printf("%s%s%s[%d]%lu\n", prefix, last_prefix, x->key, x->color, x->value); rb_graph(tr, x->left, prefix); }}key_value *rb_flatten(rbtree *tr) { int i = 0, top = 0; key_value *kvl = (key_value*) malloc(tr->size * sizeof(key_value)); rb_node *nds[tr->size]; nds[top] = tr->root; rb_node *nd; while (top >= 0) { nd = nds[top--]; if (nd != tr->nil) { kvl[i].key = nd->key; kvl[i].value = nd->value; i++; nds[++top] = nd->left; nds[++top] = nd->right; } } return kvl;}static int rb_cmp(const void *a, const void *b) { return (*(key_value *) a).value > (*(key_value *) b).value ? -1 : 1;}static void print_by_key_asce(rbtree *tr, rb_node *nd) { if (nd != tr->nil) { print_by_key_asce(tr, nd->left); printf("%s\t%lu\n", nd->key, nd->value); print_by_key_asce(tr, nd->right); }}static void print_by_value_desc(rbtree *tr) { key_value *kvl = rb_flatten(tr); size_t rb_size = tr->size; qsort(kvl, rb_size, sizeof(kvl[0]), rb_cmp); size_t i = 0; for (; i < rb_size; i++) { printf("%s\t%lu\n", kvl[i].key, kvl[i].value); } free(kvl);}
0 0
- C红黑树统计英文单词数量
- c:统计单词数量
- 统计英文单词词频(c版)
- 统计英文单词
- c:统计单词数量2
- C语言之统计输入字符数量
- c: 统计文章的单词数量
- 英文单词频率统计工具
- Java 统计英文单词
- 英文单词词频统计代码
- 统计英文单词词频
- 英文单词词频统计
- 英文单词统计程序
- C++英文单词统计小程序
- 统计文本中某值字段数量-cat-awk-sort-uniq-c
- C语言--统计混合汉字与ASCII字符串字符数量
- C#:另一种判断质数的代码,并统计数量
- ASP访问数量统计
- ArrayList源码详解
- php取到的时间总是差8小时的解决方法
- mysql 多表联合查询优化
- java web 学习总结之 Servlet/JSP 编码问题
- 函数指针和指针函数的区别
- C红黑树统计英文单词数量
- 我的算法学习之路
- android经典DEMO
- 好久没更新博客了呢~~
- 整理了一些免费的编程中文书籍
- Spark大师之路:广播变量(Broadcast)源码分析
- How to convert XML to JSON in ASP.NET C#
- 华为OJ: 公共字串计算
- Android:创建可穿戴应用 - 建立模拟器和创建项目