数据结构18:Prim算法和Dijkstra算法

摘要: Prim算法和Dijkstra算法是最小生成树和单源最短路径问题里面两个十分经典的算法,并且在我们计算机行业应用十分广泛,是基础算法。所以我们一定要掌握。代码里面有很详细的注释,如果不能很好的看懂理解的话,建议跟着图多跟踪几遍

上代码!
一.代码块
1)网的创建

实际上就跟我们的图一样,也是用邻接矩阵表示的,只不过不再是布尔矩阵,而是每条路径有权重的。

//表示无穷 
#define MAX 100000

typedef struct net
{
   
	int **weights;
	int numNode;
}*netPtr;

2)初始化

简简单单的malloc和拷贝

netPtr netInit(int paraNodes,int **paraArray)
{
   
	int i,j;
	
	//全是动态的,都要malloc 
	netPtr resultNet = (netPtr)malloc(sizeof(struct net));
	resultNet->weights = (int**)malloc(paraNodes*sizeof(int*));
	for(i = 0;i < paraNodes;i ++)
	{
   
		resultNet->weights[i] = (int*)malloc(paraNodes*sizeof(int));
	}
	
	//纯纯拷贝 
	resultNet->numNode = paraNodes;
	for(i = 0;i < paraNodes;i ++)
		for(j = 0;j < paraNodes;j ++)
			resultNet->weights[i][j] = paraArray[i][j];
			
	return resultNet;
}

3)算法函数

手动划重点,一定要理解
这里说一下两者区别的距离数组吧,距离数组只在一处地方有更新,即选出最佳结点后,最佳结点成功帮助了其他结点的时候更新。

在最短路径里面,我们需要把距离叠加,是因为我们已经有了很多路径了,我们选择的就是最短的路径,所以最终distant数组里面存放的就是从source到各个结点的最短距离。

但在最小生成树里面,我们只想构建起一个棵树,使得每一个结点都能到达任意一个结点,并且总代价最小,两者的目的是不同的,之所以两者代码区别很小,是因为都是贪心算法的缘故。所以这个算法呢distant数组里面存放的是该结点到其父节点的距离,把所有的distant 加起来,就是我们构建树的总代价。但是只有总代价是不能确定这个棵到底什么样子的,别忘了我们还有parent数组,这个会帮助我们确立唯一一棵最小生成树。

其他代码算法的细节都在代码的注释里面,建议仔细看一下

//后面一个参数单纯是为了选择用哪个算法而已 
void PrimOrDijkstra(netPtr paraNet,int paraAlgorithm)
{
   
	int i,j,tempBestNode,minDistance,resultCost;
	int *visited,*parent,*distant;
	int numNodes = paraNet->numNode;
	
	//这里是用来存放是否访问过、父节点、最短距离的数组 
	visited = (int*)malloc(sizeof(int) * paraNet->numNode);
	parent = (int*)malloc(sizeof(int) * paraNet->numNode);
	distant = (int*)malloc(sizeof(int) * paraNet->numNode);
	
	//我们默认起始点为0开始构建。 
	int source = 0;
	
	//初始化
	for(i = 0;i < paraNet->numNode;i ++)
	{
   
		visited[i] = 0;
		parent[i] = source;
		distant[i] = paraNet->weights[source][i];
	}
	
	distant[source] = 0;
	visited[source] = 1;
	parent[source] = -1;
	
	//算法开始,第一个结点已经在网中了,我们只需循环n-1次 
	for(i = 0;i < numNodes-1;i ++)
	{
   
		/*第一步,即第一个循环,实现要找到与目前结点
		项链且路径最短的那个结点为最佳结点*/
		minDistance = MAX;
		for(j = 0;j < numNodes;j ++)
		{
   
			if(distant[j] < minDistance && visited[j] == 0)
			{
   
				minDistance = distant[j];
				tempBestNode = j;
			}
		}
		//找到之后就表示他以及被放问过了,即已经入网了 
		visited[tempBestNode] = 1;
		
		/*第二步,是最佳结点要帮组其他结点了*/
		for(j = 0;j < numNodes;j ++)
		{
   
			//在网中直接下一个 
			if(visited[j] == 1)
			{
   
				continue;
			}
			
			/*后面的话初始化的时候,我们把图里面的0表示不连通直接转换为MAX无穷大了
			所有,无穷大即不连通的话直接下一个*/ 
			if(paraNet
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值