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

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

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

前两篇博客我们讨论了prim最小生成树的算法,熟悉了基本的流程。基本上来说,我们是按照自上而下的顺序来编写代码的。首先我们搭建一个架构,然后一步一步完成其中的每一个子功能,这样最后构成一个完成prim算法计算过程。

 f)将DIR_LINE队列中不符合的数据删除,主要是双节点都已经访问过的DIR_LINE数据。

void delete_unvalid_line_from_list(DIR_LINE** ppHead, MINI_GENERATE_TREE* pMiniTree)
{
	DIR_LINE* prev;
	DIR_LINE* pcur;
	STATUS result;

	prev = NULL;
	pcur = *ppHead;
	while(pcur){
		if(!check_valid_for_line(pcur, pMiniTree)){
			result = delete_line_from_queue(ppHead, pcur);
			assert(TRUE == result);

			if(NULL == prev)
				pcur = *ppHead;
			else
				pcur = prev->next;

			continue;
		}

		prev = pcur;
		pcur = pcur->next;
	}

	return;
}

g) 在f)函数中使用了判定DIR_LINE合法性的函数,我们需要完善一下。

int check_valid_for_line(DIR_LINE* pDirLine, MINI_GENERATE_TREE* pMiniTree)
{
	int index;
	int flag_start;
	int flag_end;

	flag_start = 0;
	flag_end = 0;

	for(index = 0; index < pMiniTree->node_num; index ++){
		if(pDirLine->start == pMiniTree->pNode[index]){
			flag_start = 1;
			break;
		}
	}

	for(index = 0; index < pMiniTree->node_num; index ++){
		if(pDirLine->end == pMiniTree->pNode[index]){
			flag_end = 1;
			break;
		}
	}

	return (1 == flag_start && 1 == flag_end) ? 0 : 1;
}

h) 最后就是对当前已经入队的DIR_LINE数据排序,其实就是链表排序

void insert_for_sort_operation(DIR_LINE** ppNode, DIR_LINE* pNode)
{
    DIR_LINE* prev;
    DIR_LINE* cur;  

    /* 在第一个数据之前插入pNode */
    if(pNode->weight < (*ppNode)->weight){
        pNode->next = *ppNode;
        *ppNode = pNode;
        return;
    }  

    cur = *ppNode;
    while(cur){
        if(pNode->weight < cur->weight)
            break;  

        prev = cur;
        cur = cur->next;
    }  

    pNode->next = prev->next;
    prev->next = pNode;
    return;
} 

void sort_for_line_list(DIR_LINE** ppNode)
{
	DIR_LINE* prev;
	DIR_LINE* curr;

	if(NULL == ppNode || NULL == *ppNode)
		return;

	curr = (*ppNode) ->next;
	(*ppNode) ->next = NULL;

	while(curr){
		prev = curr;
		curr = curr->next;
		insert_for_sort_operation(ppNode, prev);
	}
}

算法总结:

1)算法本身还有改进的空间,比如是不是内存分配上每一次都要重建DIR_LINE队列有待商榷

2)算法编写不是一部就位的,中间有反复更有删改,写四五次是很正常的事情

3)编写代码的时候最好做到边修改、边测试,这样可以一方面增加代码的健壮度,一方面还能提高自己的信心

4)如果存在可能,可以复用以前写过的、稳定的算法代码,比如说排序、查找、堆栈、二叉树之类的代码

时间: 2024-10-14 11:28:45

一步一步写算法(之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

图基本算法 最小生成树 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中

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

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

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中任取一