一步一步写算法(之prim算法 中)

原文:一步一步写算法(之prim算法 中)

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

C)编写最小生成树,涉及创建、挑选和添加过程

MINI_GENERATE_TREE* get_mini_tree_from_graph(GRAPH* pGraph)
{
	MINI_GENERATE_TREE* pMiniTree;
	DIR_LINE pDirLine;

	if(NULL == pGraph || NULL == pGraph->head)
		return NULL;

	pMiniTree = (MINI_GENERATE_TREE*)malloc(sizeof(MINI_GENERATE_TREE));
	assert(NULL != pMiniTree);
	memset(pMiniTree, 0, sizeof(MINI_GENERATE_TREE));

	pMiniTree->node_num = 1;
	pMiniTree->pNode = (int*)malloc(sizeof(int) * pGraph->count);
	memset(pMiniTree->pNode, 0, sizeof(int) * pGraph->count);
	pMiniTree->pNode[0] = pGraph->head->start;

	while(1){
		memset(&pDirLine, 0, sizeof(DIR_LINE));
		get_dir_line_from_graph(pGraph, pMiniTree, &pDirLine);
		if(pDirLine.start == 0)
			break;

		pMiniTree->line_num ++;
		insert_line_into_queue(&pMiniTree->pLine, pDirLine.start, pDirLine.end, pDirLine.weight);
		insert_node_into_mini_tree(&pDirLine, pMiniTree);
	}

	return pMiniTree;
}

d) 构建挑选函数,选择最合适的边

void get_dir_line_from_graph(GRAPH* pGraph, MINI_GENERATE_TREE* pMiniTree, DIR_LINE* pDirLine)
{
	DIR_LINE* pHead;
	DIR_LINE* prev;
	VECTEX* pVectex;
	LINE* pLine;
	int index;
	int start;

	pHead = NULL;
	for(index = 0; index < pMiniTree->node_num; index++){
		start = pMiniTree->pNode[index];
		pVectex = find_vectex_in_graph(pGraph->head, start);
		pLine = pVectex->neighbor;

		while(pLine){
			insert_line_into_queue(&pHead, start, pLine->end, pLine->weight);
			pLine = pLine->next;
		}
	}

	if(NULL == pHead)
		return;

	delete_unvalid_line_from_list(&pHead, pMiniTree);
	if(NULL == pHead)
		return;

	sort_for_line_list(&pHead);
	memmove(pDirLine, pHead, sizeof(DIR_LINE));

	while(pHead){
		prev = pHead;
		pHead = pHead->next;
		free(prev);
	}
	return;
}

e)添加节点函数,将尚不是最小生成树的点纳入到最小生成树当中去

void insert_node_into_mini_tree(DIR_LINE* pLine, MINI_GENERATE_TREE* pMiniTree)
{
	int index;

	for(index = 0; index < pMiniTree->node_num; index ++){
		if(pLine->start == pMiniTree->pNode[index]){
			pMiniTree->pNode[pMiniTree->node_num++] = pLine->end;
			return;
		}
	}

	pMiniTree->pNode[pMiniTree->node_num++] = pLine->start;
	return;
}

注意事项:

(1)d、e是c中调用的子函数,如果大家观察一下就明白了

(2)最小生成树是按照自顶向下的顺序编写的,虽然c中的子函数完成了,但是d中还有两个子函数没有着落

(3)d中的函数delete_unvalid_line_from_list、sort_for_line_list会在下一篇中继续介绍

(4)算法只要能够按照手工计算的流程编写出来,基本上问题不大,但是一些细节还是要小心注意的

【待续】

时间: 2024-11-10 15:30:10

一步一步写算法(之prim算法 中)的相关文章

hdu 1162 Eddy&amp;#39;s picture (Kruskal算法,prim算法,最小生成树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1162 [题目大意] 给你n个点的坐标,让你找到联通n个点的一种方法.保证联通的线路最短,典型的最小生成树问题. 方法一 . 通过不断找到最小的边来找到终于结果. Kruskal 算法 #include <iostream> #include <algorithm> #include <cstdio> #include <cmath> using namespac

hdu 1162 Eddy&#39;s picture (Kruskal算法,prim算法,最小生成树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1162 [题目大意] 给你n个点的坐标,让你找到联通n个点的一种方法,保证联通的线路最短,典型的最小生成树问题. 方法一 , 通过不断找到最小的边来找到最终结果. Kruskal 算法 #include <iostream> #include <algorithm> #include <cstdio> #include <cmath> using namespac

转 最小生成树(kruskal 算法 和prim算法)

链接:http://blog.csdn.net/weinierbian/article/details/8059129/ 给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树. 求最小生成树的算法(1) 克鲁斯卡尔算法图的存贮结构采用边集数组,且权值相等的边在数组中排列次序可以是任意的.该方法对于边相对比较多的不是很实用,浪费时间.(2) 普里姆算法图的存贮结构采用邻接矩阵.此方法是按各个顶点连通的步骤进行,需要用一个顶点集合,开始为空集,以后将以连通的顶点

图基本算法 最小生成树 Prim算法(邻接表+优先队列STL)

这篇文章是对<算法导论>上Prim算法求无向连通图最小生成树的一个总结,其中有关于我的一点点小看法. 最小生成树的具体问题可以用下面的语言阐述: 输入:一个无向带权图G=(V,E),对于每一条边(u, v)属于E,都有一个权值w. 输出:这个图的最小生成树,即一棵连接所有顶点的树,且这棵树中的边的权值的和最小. 举例如下,求下图的最小生成树: 这个问题是求解一个最优解的过程.那么怎样才算最优呢? 首先我们考虑最优子结构:如果一个问题的最优解中包含了子问题的最优解,则该问题具有最优子结构. 最小

最小生成树算法 1.Prim算法

最小生成树(MST):一个有N个点的图,边一定是大于等于N-1条边的.在这些边中选择N-1条出来,连接所有N个点.这N-1条边的边权之和是所有方案中最小的. Prim算法的时间复杂度时O(n^2)的,因此适用于稠密图的最小生成树,如果是稀疏图的情况下采用Kruskal算法更好. Prim算法蕴含了贪心的思想,其原理是把图中所有的点分成两个集合,一个集合(V)是已经在生成树中的点,另一个集合(G)是不在生成树中的点,然后寻找起点在V中,终点在G中的边中权值最小的边加入生成树,然后把终点从G移到V中

Dijkstra算法与Prim算法辨析

这两个算法真的很像,尽管它们的用处截然不同. Dijkstra是找单源非负的最短路径. Prim是找最小生成树. Dijkstra算法都是找当前标记集合点再扩一条边所形成的最短路径,然后更新标记点集,外扩路径集. Prim是找当前标记集合点再扩一条边中所形成的的最短边,然后更新标记点集,外扩边集. 所以细节上是有不同的. Dijkstra复杂度O(N2), Prim O(eloge).

数据结构与算法系列----最小生成树(Prim算法&amp;amp;Kruskal算法)

 一:Prim算法       1.概览 普里姆算法(Prim算法).图论中的一种算法.可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中.不但包含了连通图里的全部顶点(英语:Vertex (graph theory)).且其全部边的权值之和亦为最小. 该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现.并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现:1959年,艾兹格·迪科斯彻再次发现了该

【最小生成树】prim算法

算法分析的一般步骤: 1.文字描述:如果一个算法文字描述不清楚,就说明思路不清楚,也不可能写好. prim算法是实现图的最小生成树.既然是图,就假设包含n个顶点,m条边.prim算法是从顶点出发的,其算法时间复杂度与顶点数目有关系. (注意:prim算法适合稠密图,其时间复杂度为O(n^2),其时间复杂度与边得数目无关,而kruskal算法的时间复杂度为O(eloge)跟边的数目有关,适合稀疏图.) 算法思路:从某个顶点开始,假设v0,此时v0属于最小生成树结点中的一个元素,该集合假设u,剩下的

[迷宫中的算法实践]迷宫生成算法&mdash;&mdash;Prim算法

       普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小.该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现:并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现:1959年,艾兹格·迪科斯彻再次发现了该算法.因此,在某些场合,普里姆

数据结构(C实现)------- 最小生成树之Prim算法

[本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020] 算法描述 如果连通图是一个网,则称该网中所有生成树中权值总和最小的生成树为最小生成树,也称最小代价生成树.利用Prim算法构造的最小生成树方法思想: 假设G=(V,E)是一个具有n个顶点的连通网,顶点集V={v1,v2,...,vn}.设所求的最小生成树T=(U,TE),其中U是T的顶点集,TE是T的边集,U和TE初值均为空集. Prim算法的基本思想如下:首先从V中任取一