根据算法导论给出的算法实现。
代码如下:
1.h:
#ifndef _MST_KRUSKAL_H_
#define _MST_KRUSKAL_H_
struct edge
{
int value;
int x;
int y;
// int rank;
// struct edge *p;
};
struct vertex
{
struct vertex *p;
int rank;
};
//quick sort
void quick_sort(void *data, int count, int size, int (*compare)(const void *, const void *));
//disjoint set
void make_set(struct vertex *e);
struct vertex * find_set(struct vertex *x);
void union_set(struct vertex *x, struct vertex *y);
//kruskal alogirthm
#endif
1.c:
#include "1.h"
void swap(void *p, void *q, int size)
{
unsigned char *x = (unsigned char *)p;
unsigned char *y = (unsigned char *)q;
int i;
for(i = 0; i < size; i++)
{
unsigned char tmp = x[i];
x[i] = y[i];
y[i] = tmp;
}
}
int get_partition(void *data, int p, int q, int size, int (*compare)(const void *, const void *))
{
// int x = data[q];
int i;
int j = p-1;
void *x = data + q * size;
for(i = p; i < q; i++)
{
void *c = data + i * size;
if(compare(c, x) < 0)
{
j++;
int k;
void *s = data + j * size;
swap(c, s, size);
// int tmp = data[i];
// data[i] = data[j];
// data[j] = tmp;
}
}
j++;
swap(data + j * size, x, size);
return j;
}
void _quick_sort(void *data, int p, int q, int size, int (*compare)(const void *, const void *))
{
if(p < q)
{
int r = get_partition(data, p, q, size, compare);
_quick_sort(data, p, r-1, size, compare);
_quick_sort(data, r+1, q, size, compare);
}
}
void quick_sort(void *data, int count, int size, int (*compare)(const void *, const void *))
{
_quick_sort(data, 0, count -1, size, compare);
}
void make_set(struct vertex *v)
{
v->p = v;
v->rank = 0;
}
struct vertex *find_set(struct vertex *v)
{
if(v->p != v)
{
v->p = find_set(v->p);
}
return v->p;
}
void union_set(struct vertex *x, struct vertex *y)
{
struct vertex *a = find_set(x);
struct vertex *b = find_set(y);
if(a->rank < b->rank)
{
a->p = b;
}
else
{
b->p = a;
if(b->rank == a->rank)
{
a->rank = a->rank + 1;
}
}
}
test.c
#include "1.h"
#include <stdio.h>
int number_of_vertices, number_of_edges;
struct edge myedges[100];
struct vertex myvertices[100];
struct edge resultedges[100];
int number_of_result_edges;
int minimum_total_cost;
int compare(const void *a, const void *b)
{
struct edge *pA = (struct edge *)a;
struct edge *pB = (struct edge *)b;
if(pA->value > pB->value)
{
return 1;
}
else if(pA->value < pB->value)
{
return -1;
}
else
{
return 0;
}
}
void get_data(void)
{
scanf("%d %d", &number_of_vertices, &number_of_edges);
int i;
for(i = 0; i < number_of_edges; i++)
{
scanf("%d %d %d", &myedges[i].x, &myedges[i].y, &myedges[i].value);
}
}
int main(void)
{
get_data();
int i;
for(i = 0; i < number_of_vertices; i++)
{
make_set(&myvertices[i]);
}
quick_sort(myedges, number_of_edges, sizeof(struct edge), compare);
for(i = 0; i < number_of_edges; i++)
{
struct vertex *x = &myvertices[myedges[i].x];
struct vertex *y = &myvertices[myedges[i].y];
if(find_set(x) != find_set(y))
{
resultedges[number_of_result_edges] = myedges[i];
number_of_result_edges++;
minimum_total_cost += myedges[i].value;
union_set(x, y);
}
}
return 0;
}
执行结果:
(gdb) p resultedges
$2 = {{value = 1, x = 6, y = 7}, {value = 2, x = 8, y = 2}, {value = 2, x = 5, y = 6}, {value = 4, x = 2, y = 5}, {
value = 4, x = 0, y = 1}, {value = 7, x = 2, y = 3}, {value = 8, x = 7, y = 0}, {value = 9, x = 3, y = 4}, {
value = 0, x = 0, y = 0} <repeats 92 times>}
(gdb) p minimum_total_cost
$3 = 37
和书上给出的例子结果一样。
输入数据:
9 14
0 1 4
1 2 8
2 3 7
3 4 9
4 5 10
5 6 2
6 7 1
7 8 7
8 2 2
2 5 4
3 5 14
6 8 6
7 0 8
7 1 11