算法导论代码 第21章 用于不相交集合的数据结构

来源:互联网 发布:家具画图软件 编辑:程序博客网 时间:2024/05/01 08:25

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-1char 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-1char 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;}



原创粉丝点击