`
Touch_2011
  • 浏览: 290485 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

最小生成树(C语言实现)

阅读更多

求这个网的最小生成树

/*
 * 普里姆算法和克鲁斯卡尔算法求最小生成树
 * 采用邻接矩阵存储
 *
 */
#include<stdio.h>

#define MAX_VERTEX_NUM 20
//图的定义
typedef struct 
{
	int vertexNum;
	int edgeNum;
	char vertex[MAX_VERTEX_NUM];
	int arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
}Graph,*PGraph;

//辅助数组元素
typedef struct 
{
	int from;
	int to;
	int weight;
	int flag;
}ArrayNode; 

//构造无向网
void createdGraph(PGraph g)
{
	int i,j;
    g->vertexNum=6;
	g->edgeNum=10;
    for(i=0;i<g->vertexNum;i++)
		g->vertex[i]='A'+i;
	for(i=0;i<g->vertexNum;i++)
		for(j=0;j<g->vertexNum;j++)
            g->arc[i][j]=0;
	g->arc[0][1]=6;
	g->arc[0][2]=1;
	g->arc[0][3]=5;
	g->arc[1][0]=6;
	g->arc[1][2]=5;
	g->arc[1][4]=3;
	g->arc[2][0]=1;
	g->arc[2][1]=5;
	g->arc[2][3]=5;
	g->arc[2][4]=6;
	g->arc[2][5]=4;
	g->arc[3][0]=5;
	g->arc[3][2]=5;
	g->arc[3][5]=2;
	g->arc[4][1]=3;
	g->arc[4][2]=6;
	g->arc[4][5]=6;
	g->arc[5][2]=4;
	g->arc[5][3]=2;
	g->arc[5][4]=6;
}

//初始化最小生成树
void initTree(PGraph tree)
{
	int i,j;
    tree->vertexNum=6;
	tree->edgeNum=5;
	for(i=0;i<tree->vertexNum;i++)
		tree->vertex[i]='0';
	for(i=0;i<tree->vertexNum;i++)
		for(j=0;j<tree->vertexNum;j++)
            tree->arc[i][j]=0;
}

//普里姆算法求最小生成树
void prim(PGraph g,PGraph tree)
{
	int i,j,k;
	int index;  //指向权值最小的边
    ArrayNode  edgeArray[MAX_VERTEX_NUM*2]; //辅助数组 
	int length=0; //数组长度
	int n=1;  //统计数组已加入多少个顶点

	//初始状态把第一个顶点加入树中
	tree->vertex[0]='A';
	printf("%-3c",tree->vertex[0]);
    i=0;
    while(1){
    	//寻找与顶点i相接且这条边的另一个顶点不在树中的边,存入edgeArray数组中
		for(j=0;j<g->vertexNum;j++){
			if(g->arc[i][j] > 0){
				//判断这条边的另一个顶点在不在树中
				for(k=0;k<tree->vertexNum;k++){
					if(tree->vertex[k] == g->vertex[j])
						break;
				}
				if(k == tree->vertexNum){
                    edgeArray[length].from=i;
		            edgeArray[length].to=j;
	    			edgeArray[length].weight=g->arc[i][j];
                    edgeArray[length].flag=0;
		    		length++;
				}
			}
		}
		//从数组中选择权值最小的边
		index=-1;
		for(j=0;j<length;j++){
			if(index == -1 && edgeArray[j].flag == 0)
				index=j;
            if(edgeArray[j].flag==0 && edgeArray[j].weight < edgeArray[index].weight)
				index=j;
		}
		//在树中加入一个顶点,且把这条权值最小的边加入树中
		tree->vertex[edgeArray[index].to]='A'+edgeArray[index].to;
        edgeArray[index].flag=1;
		tree->arc[edgeArray[index].from][edgeArray[index].to]=edgeArray[index].weight;
		tree->arc[edgeArray[index].to][edgeArray[index].from]=edgeArray[index].weight;
		//当这个顶点加入树中时,与这个顶点相邻的边不可加入树中
		for(k=0;k<length;k++){
			if(edgeArray[k].to == edgeArray[index].to)
				edgeArray[k].flag=1;
		}
		i=edgeArray[index].to;
		printf("%-3c",tree->vertex[i]);
		n++;
		//当有g->vertexNum个顶点时,最小生成树构造完成
		if(n==g->vertexNum)
			break;
	}
}

//判断两个顶点是否连通(广度优先搜索)
int connected(PGraph tree,int from,int to)
{
	int i,j,k;
	int vertex[MAX_VERTEX_NUM];//看成队列
	int front,rear;
	if(from==to)
		return 1;
	front=rear=0;
	//把第一个顶点存入数组
	vertex[rear++]=from;
	//遍历tree
	while(front<=rear){
		i=vertex[front];
        for(j=0;j<tree->vertexNum;j++)
			if(tree->arc[i][j]>0){
				if(j==to)
					return 1;
				//判断此顶点是否在队列中
				for(k=0;k<rear;k++)
					if(vertex[k] == j)
						break;
				if(k==rear)
     			    vertex[rear++]=j;
			}
		front++;
	}
	return 0;
}

//克鲁斯卡尔算法求最小生成树
void kruskal(PGraph g,PGraph tree)
{
    ArrayNode  edgeArray[MAX_VERTEX_NUM]; //辅助数组 
	int length=0;
	int i,j,k,index,n;

	//顶点先加入树中
	for(i=0;i<tree->vertexNum;i++)
		tree->vertex[i]=i+'A';
	//1.把所有的边有序(从小到大)的插入edgeArray数组中
	for(i=0;i<g->vertexNum;i++)
		for(j=0;j<g->vertexNum;j++){
			if(i<j && g->arc[i][j]>0){
				//寻找插入的位置index
				for(k=0;k<length;k++){
                    if(edgeArray[k].weight > g->arc[i][j])
						break;
				}
				index=k;
                //移位
				for(k=length;k>index;k--)
                    edgeArray[k]=edgeArray[k-1];
				//插入
				length++;
				edgeArray[index].flag=0;
				edgeArray[index].from=i;
				edgeArray[index].to=j;
				edgeArray[index].weight=g->arc[i][j];
			}
		}
	//2.从小到大取出n-1条边构造最小生成树
	n=0;
	while(n < g->vertexNum-1){
		//从小到大取一条符合要求的边
		for(k=0;k<length;k++)
			if(edgeArray[k].flag==0 && connected(tree,edgeArray[k].from,edgeArray[k].to)==0){
				break;
			}
		//把这条边加入树中
		tree->arc[edgeArray[k].from][edgeArray[k].to]=edgeArray[k].weight;
		tree->arc[edgeArray[k].to][edgeArray[k].from]=edgeArray[k].weight;
        edgeArray[k].flag=1;
		printf("%-3d",edgeArray[k].weight);
		n++;
	}
}

void main()
{
	Graph graph;
	Graph tree;
	createdGraph(&graph);
	initTree(&tree);
	printf("普里姆算法树中顶点加入的顺序:\n");
	prim(&graph,&tree);
	printf("\n");
	initTree(&tree);
	printf("克鲁斯卡尔算法树中边加入的顺序:\n");
	kruskal(&graph,&tree);
	printf("\n");
}

 

  • 大小: 19.7 KB
0
1
分享到:
评论

相关推荐

    最小生成树c语言实现

    本主题将详细探讨如何用C语言实现最小生成树算法。 首先,我们需要理解两种常用的最小生成树算法:Prim算法和Kruskal算法。 1. **Prim算法**: - Prim算法从一个初始顶点开始,逐步添加边,每次选择当前未加入树...

    C语言实现的最小生成树源代码

    本文将介绍如何使用C语言实现两种经典算法——普里姆算法和克鲁斯卡尔算法来找到一个无向加权图的最小生成树。 普里姆算法是一种贪心算法,它通过逐步增加边来构建最小生成树。在C语言中,我们可以这样实现: 1. ...

    最小生成树C语言

    数据结构最小生成树,C语言源代码,感兴趣的可以看一下。

    最小生成树 C语言

    在提供的压缩包文件中,“最小生成树”很可能包含了这些算法的C语言实现代码,你可以通过阅读和分析这些代码来深入理解和学习最小生成树算法。同时,这些代码也可以作为你进行毕业设计或课程设计的参考,帮助你构建...

    最小生成树kruskal算法并查集版 C语言实现 - Slyar Home

    最小生成树kruskal算法并查集版 C语言实现 - Slyar Home

    c语言实现最小生成树算法

    ### c语言实现最小生成树算法 #### 知识点概览 本文将详细介绍如何使用C语言来实现最小生成树(Minimum Spanning Tree, MST)算法,并重点解释Prim算法的实现过程与代码细节。 #### 最小生成树算法简介 在图论中,...

    最小生成树计数结题报告与代码

    理解和实现最小生成树计数不仅要求掌握图论基础,还需要对动态规划、矩阵运算以及算法优化有深入的理解。 在实际应用中,最小生成树计数的问题可能出现在多个领域,如网络设计、运输路线规划、甚至是社交网络分析等...

    cpp-图论算法最小生成树Prim算法和Kruskal算法C实现

    本文将详细介绍两种经典算法来解决最小生成树问题:Prim算法和Kruskal算法,并以C语言实现为例进行讲解。 ### Prim算法 Prim算法是一种贪心算法,其基本思想是从一个初始节点开始,逐步添加最短的边,直到连接到...

    最小生成树Kruskal算法

    编写算法能够建立带权图,并能够用Kruskal算法求该图的最小生成树。最小生成树能够选择图上的任意一点做根结点。最小生成树输出采用顶点集合和边的集合的形式。

    用c语言实现最小生成树问题

    在C语言中实现最小生成树,通常会使用两种经典的算法:Prim算法和Kruskal算法。Prim算法是一种贪心策略,从一个顶点开始,逐步添加边到树中,每次都选择与当前树连接且权重最小的边。Kruskal算法则按照边的权重从小...

    最小生成树Prim算法的C语言程序

    "最小生成树Prim算法的C语言程序" Prim 算法是最小生成树的一种特殊算法,它的特点是集合 A 的边总是只形成单棵树。该算法的基本思路是:任选一个顶点(本实验取①为起始点),将其涂红,其余顶点为白点;在一个...

    构造可以使n个城市连接的最小生成树

    #### 数据结构设计:最小生成树与C语言实现 在计算机科学领域,图论中的最小生成树(Minimum Spanning Tree, MST)问题是一个经典问题,广泛应用于网络设计、电路板设计等多个方面。最小生成树是指在一个加权的连通...

    C例子:最小生成树(kruskal)

    该程序是我写的博客“一起talk C栗子吧(第五十回:C语言实例--最小生成树二)”的配套程序,共享给大家使用

    数据结构 最小生成树C代码

    在这里,我们使用C语言实现了克鲁斯卡尔算法,以解决最小生成树问题。 该代码主要分为三个部分: 1. 图的创建:我们使用了一个名为Graph的类来表示图,图中每个节点对应一个Bian对象,Bian对象中存储了边的权值、...

    c语言编写的最小生成树

    最小生成树是图论中的一个重要概念,用于...通过对这些知识点的理解和实践,你将能够熟练掌握C语言实现最小生成树的方法,并能将其应用到实际问题中。同时,这种算法的训练也有助于提高你的编程能力和解决问题的能力。

    普利姆算法求最小生成树 c源码

    总结来说,普利姆算法是解决最小生成树问题的一种高效方法,它的C++实现涉及到图的数据结构、优先队列和迭代更新等核心概念。通过学习和实践这个算法,你可以加深对图论和数据结构的理解,提高编程能力。

    最小生成树kruskal算法并查集版+C语言实现

    综上所述,最小生成树的Kruskal算法结合并查集是解决图问题的一种有效方法,通过C语言实现可以更好地理解和掌握算法的细节。在实际应用中,可以根据具体需求调整并查集的实现,以满足性能要求。

    最小生成树 数据结构 C语言编程

    根据给定文件的信息,...综上所述,通过上述知识点的梳理,我们不仅了解了最小生成树的基本概念,还掌握了如何使用C语言实现Kruskal算法求解最小生成树的具体方法。这对于深入理解数据结构与算法的应用具有重要意义。

Global site tag (gtag.js) - Google Analytics