#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) ;//清除树tr
rb_node *rb_search(rbtree *tr, rb_key z) ;//根据key查找结点,找到返回指针,找不到则返回NULL
void 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);
}
C红黑树统计英文单词数量
最新推荐文章于 2020-08-22 16:39:10 发布