Kruskal 算法实现

本文介绍了一种基于克鲁斯卡尔算法的最小生成树构建方法,并提供了详细的C语言实现代码。该实现包括快速排序、不相交集管理和核心算法过程,通过实例演示了如何从加权图中找出总权重最小的生成树。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据算法导论给出的算法实现。

代码如下:

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值