算法导论代码 第21章 用于不相交集合的数据结构
2011-12-30 18:10
381 查看
第21章 用于不相交集合的数据结构
21.2 不相交集体的链表表示
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct set_type *set; struct set_node { void *key; struct set_node *next; struct set_node *representative; //指向代表的集合元素 }; struct set_type { struct set_node *head; struct set_node *tail; int num; }; void set_node_ini(struct set_node *x, void *key) { x->key = key; x->next = NULL; x->representative = NULL; } set set_create(void *key) { set s = malloc(sizeof(struct set_type)); struct set_node *x = malloc(sizeof(struct set_node)); set_node_ini(x, key); s->head = x; s->tail = x; s->num = 1; x->representative = x; return s; } struct set_node *find_set(set s) { return s->head->representative; } void update_representative(struct set_node *head, struct set_node *representative) { struct set_node *p = head; while (p != NULL) { p->representative = representative; p = p->next; } } //把较短的链表拼到较长的链表上,更新短链表的每个结点指向代表指针 void set_union(set sa, set sb) { if (sa->num < sb->num) { update_representative(sa->head, sb->head); sb->tail->next = sa->head; sa->head = sb->head; } else { update_representative(sb->head, sa->head); sa->tail->next = sb->head; sa->tail = sb->tail; } sa->num += sb->num; } void set_destroy(set s, void (*free_key) (void *)) { free_key(s->head->key); free(s->head); free(s); } struct edge { char u; char v; }; int main() { //数据根据书上图21-1 char vertex[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }; set s[256] = { NULL }; struct edge edge_array[] = { {'b', 'd'}, {'e', 'g'}, {'a', 'c'}, {'h', 'i'}, {'a', 'b'}, {'e', 'f'}, {'b', 'c'} }; int vertex_num = sizeof(vertex) / sizeof(vertex[0]); for (int i = 0; i < vertex_num; i++) { char *c = malloc(sizeof(char)); *c = vertex[i]; s[(int)vertex[i]] = set_create(c); } //计算连通子图 for (unsigned i = 0; i < sizeof(edge_array) / sizeof(edge_array[0]); i++) { set su = s[(int)edge_array[i].u]; set sv = s[(int)edge_array[i].v]; if (find_set(su) != find_set(sv)) { set_union(su, sv); } } //输出连通子图 char str_set[256][256] = { {0} }; for (int i = 0; i < vertex_num; i++) { char *pc = find_set(s[(int)vertex[i]])->key; int len = strlen(str_set[(int)*pc]); str_set[(int)*pc][len] = vertex[i]; } printf("输出不相交集合组:\n"); for (int i = 0; i < vertex_num; i++) { if (strcmp(str_set[(int)vertex[i]], "") != 0) { printf("%s\n", str_set[(int)vertex[i]]); } } for (int i = 0; i < vertex_num; i++) { set sv = s[(int)vertex[i]]; set_destroy(sv, free); } return 0; }
21.3 不相交集合森林
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct set_type *set; struct set_node { void *key; int rank; struct set_node *parent; }; void set_node_ini(struct set_node *x, void *key) { x->key = key; x->rank = 0; x->parent = NULL; } struct set_type { struct set_node *root; }; set set_create(void *key) { set s = malloc(sizeof(struct set_type)); s->root = malloc(sizeof(struct set_node)); set_node_ini(s->root, key); s->root->parent = s->root; s->root->rank = 0; return s; } void link(struct set_node *x, struct set_node *y) { if (x->rank > y->rank) { y->parent = x; } else { x->parent = y; if (x->rank == y->rank) { ++y->rank; } } } struct set_node *find_set_path_compression(struct set_node *x) { if (x != x->parent) { x->parent = find_set_path_compression(x->parent); } return x->parent; } struct set_node *find_set(set s) { return find_set_path_compression(s->root); } void set_destroy(set s, void (*free_key) (void *)) { free_key(s->root->key); free(s->root); free(s); } void set_union(set sa, set sb) { link(find_set(sa), find_set(sb)); } struct edge { char u; char v; }; int main() { //数据根据书上图21-1 char vertex[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }; set s[256] = { NULL }; struct edge edge_array[] = { {'b', 'd'}, {'e', 'g'}, {'a', 'c'}, {'h', 'i'}, {'a', 'b'}, {'e', 'f'}, {'b', 'c'} }; int vertex_num = sizeof(vertex) / sizeof(vertex[0]); for (int i = 0; i < vertex_num; i++) { char *c = malloc(sizeof(char)); *c = vertex[i]; s[(int)vertex[i]] = set_create(c); } //计算连通子图 for (unsigned i = 0; i < sizeof(edge_array) / sizeof(edge_array[0]); i++) { set su = s[(int)edge_array[i].u]; set sv = s[(int)edge_array[i].v]; if (find_set(su) != find_set(sv)) { set_union(su, sv); } } //输出连通子图 char str_set[256][256] = { {0} }; for (int i = 0; i < vertex_num; i++) { char *pc = find_set(s[(int)vertex[i]])->key; int len = strlen(str_set[(int)*pc]); str_set[(int)*pc][len] = vertex[i]; } printf("输出不相交集合组:\n"); for (int i = 0; i < vertex_num; i++) { if (strcmp(str_set[(int)vertex[i]], "") != 0) { printf("%s\n", str_set[(int)vertex[i]]); } } for (int i = 0; i < vertex_num; i++) { set sv = s[(int)vertex[i]]; set_destroy(sv, free); } return 0; }
相关文章推荐
- 算法导论习题解-第21章用于不相交集合的数据结构
- 算法导论 第21章 用于不相交集合的数据结构
- 算法导论 第21章 用于不相交集合的数据结构
- 算法导论 第21章 不相交集合的数据结构
- 用于不相交集合的数据结构(算法导论第21章-并查集)
- 算法导论 第二十一章 用于不相交集合的数据结构
- 算法导论笔记:21用于不相交集合的数据结构
- 算法导论用于不相交集合的数据结构
- 算法导论21(用于不相交集合的数据结构)
- 算法导论之用于不相交集合的数据结构
- 算法导论学习笔记-第二十一章-用于不相交集合的数据结构
- 第21章:用于不相交集合的数据结构
- 算法导论——用于不相交集合的数据结构
- 算法导论-用于不相交集合的数据结构
- 算法导论-用于不想交集合的数据结构(并查集)-kruskal最小生成树算法
- 并查集(用于不相交集合的数据结构)
- 算法导论 第二十一章:不相交集合的数据结构
- 并查集——用于不相交集合的数据结构
- 用于不相交集合的数据结构
- 用于不相交集合的数据结构(并查集)