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

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

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

    前面我们讨论了图的创建、添加、删除和保存等问题。今天我们将继续讨论图的一些其他问题,比如说如何在图的环境下构建最小生成树。为什么要构建最小生成树呢?其实原理很简单。打个比方,现在某一个乡镇有n个村,那么这n个村肯定是联通的。现在我们打算在各个村之间搭建网线,实现村村通的工程。那么有什么办法可以实现村村互通,同时又使得最后的总距离最小呢?要达到这个目的,就必须在已有的图中构建最小生成树。

    生成最小生成树的方法很多,prim方法就是其中的一种。那么生成最小生成树的基本步骤是什么呢?很简单,听我慢慢道来:

    1)以某一个点开始,寻找当前该点可以访问的所有的边;

    2)在已经寻找的边中发现最小边,这个边必须有一个点还没有访问过,将还没有访问的点加入我们的集合,记录添加的边;

    3)寻找当前集合可以访问的所有边,重复2的过程,直到没有新的点可以加入;

    4)此时由所有边构成的树即为最小生成树。

   

     那么,代码应该怎么编写呢?朋友们可以自己好好思考一下。

     a)首先,我们定义基本的数据结构。

typedef struct _DIR_LINE
{
	int start;
	int end;
	int weight;
	struct _DIR_LINE* next;
}DIR_LINE;

typedef struct _MINI_GENERATE_TREE
{
	int node_num;
	int line_num;
	int* pNode;
	DIR_LINE* pLine;
}MINI_GENERATE_TREE;

    b)DIR_LINE的基本操作

STATUS insert_line_into_queue(DIR_LINE** ppLine, int start, int end, int weight)
{
	DIR_LINE* pLine;

	if(NULL == ppLine)
		return FALSE;

	if(NULL == *ppLine){
		*ppLine = create_new_dir_line(start, end, weight);
		return TRUE;
	}

	pLine = create_new_dir_line(start, end, weight);
	pLine->next = *ppLine;
	*ppLine = pLine;
	return TRUE;
}

STATUS delete_line_from_queue(DIR_LINE** ppLine, DIR_LINE* pLine)
{
	DIR_LINE* prev;

	if(NULL == ppLine || NULL == *ppLine || NULL == pLine)
		return FALSE;

	if(pLine == *ppLine){
		*ppLine = pLine->next;
		goto final;
	}

	prev = *ppLine;
	while(pLine != prev->next)
		prev = prev->next;
	prev->next = pLine->next;

final:
	free(pLine);
	return TRUE;
}

【未完,待续】

时间: 2024-09-18 22:21:19

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

最小生成树算法之Prim算法_C 语言

本文介绍了最小生成树的定义,Prim算法的实现步骤,通过简单举例实现了C语言编程. 1.什么是最小生成树算法? 简言之,就是给定一个具有n个顶点的加权的无相连通图,用n-1条边连接这n个顶点,并且使得连接之后的所有边的权值之和最小.这就叫最小生成树算法,最典型的两种算法就是Kruskal算法和本文要讲的Prim算法. 2.Prim算法的步骤是什么? 这就要涉及一些图论的知识了. a.假定图的顶点集合为V,边集合为E. b.初始化点集合U={u}.//u为V中的任意选定的一点 c.从u的邻接结点中

经典算法题每日演练——第十四题 Prim算法

        图论在数据结构中是非常有趣而复杂的,作为web码农的我,在实际开发中一直没有找到它的使用场景,不像树那样的频繁使用,不过还是准备 仔细的把图论全部过一遍. 一:最小生成树        图中有一个好玩的东西叫做生成树,就是用边来把所有的顶点联通起来,前提条件是最后形成的联通图中不能存在回路,所以就形成这样一个 推理:假设图中的顶点有n个,则生成树的边有n-1条,多一条会存在回路,少一路则不能把所有顶点联通起来,如果非要在图中加上权重,则生成树 中权重最小的叫做最小生成树. 对于上

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

原文:一步一步写算法(之prim算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前两篇博客我们讨论了prim最小生成树的算法,熟悉了基本的流程.基本上来说,我们是按照自上而下的顺序来编写代码的.首先我们搭建一个架构,然后一步一步完成其中的每一个子功能,这样最后构成一个完成prim算法计算过程.     f)将DIR_LINE队列中不符合的数据删除,主要是双节点都已经访问过的DIR_LINE数据. void delete

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

一步一步写算法(之克鲁斯卡尔算法 下)

原文:一步一步写算法(之克鲁斯卡尔算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前面在讨论克鲁斯卡尔的算法的时候,我们分析了算法的基本过程.基本数据结构和算法中需要解决的三个问题(排序.判断.合并).今天,我们继续完成剩下部分的内容.合并函数中,我们调用了两个基本函数,find_tree_by_index和delete_mini_tree_from_group,下面给出详细的计算过程. MINI_GENERATE_T

一步一步写算法(之 算法总结)

原文:一步一步写算法(之 算法总结) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]       自10月初编写算法系列的博客以来,陆陆续续以来写了几十篇.按照计划,还有三个部分的内容没有介绍,主要是(Dijkstra算法.二叉平衡树.红黑树).这部分会在后面的博客补充完整.这里主要是做一个总结,有兴趣的朋友可以好好看看,欢迎大家提出宝贵意见.       (1) 排序算法     快速排序           合并排序     堆排序

一步一步写算法(之克鲁斯卡尔算法 上)

原文:一步一步写算法(之克鲁斯卡尔算法 上) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     克鲁斯卡尔算法是计算最小生成树的一种算法.和prim算法(上,中,下)按照节点进行查找的方法不一样,克鲁斯卡尔算法是按照具体的线段进行的.现在我们假设一个图有m个节点,n条边.首先,我们需要把m个节点看成m个独立的生成树,并且把n条边按照从小到大的数据进行排列.在n条边中,我们依次取出其中的每一条边,如果发现边的两个节点分别位于两棵树上,

一步一步写算法(之二叉树深度遍历)

原文:一步一步写算法(之二叉树深度遍历) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     深度遍历是软件开发中经常遇到的遍历方法.常用的遍历方法主要有下面三种:(1)前序遍历:(2)中序遍历:(3)后序遍历.按照递归的方法,这三种遍历的方法其实都不困难,前序遍历就是根-左-右,中序遍历就是左-根-右,后续遍历就是左-右-根.代码实现起来也不复杂.     1)前序遍历 void preorder_traverse(TREE_NOD

一步一步写算法(之线性结构的处理)

原文:一步一步写算法(之线性结构的处理) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     我们知道,在内存中的空间都是连续的.也就是说,0x00000001下面的地址必然是0x00000002.所以,空间上是不会出现地址的突变的.那什么数据结构类型是连续内部空间呢,其实就是数组,当然也可以是堆.数组有很多优势,它可以在一段连续空间内保存相同类型的数据,并且对这些数据进行管理.所以从这个意义上说,掌握了数组才能说明你数据结构入门了.