Prim与Dijkstra算法

1.代码如下

#include<stdio.h>
#include<malloc.h> 

#define MAX_DISTANCE 10000

/**
*a structure of a net
*/

typedef struct Net {
	int **weights;
	int numNodes;
} Net,*NetPtr;

/**
*Intialize a net.
*/ 

NetPtr initNet(int paraSize,int **paraData){
	int i,j;
	NetPtr resultPtr = (NetPtr)malloc(sizeof(Net));
	resultPtr->numNodes = paraSize;

    //Two stage space allocation.
	resultPtr->weights = (int**)malloc(paraSize * sizeof(int *));
    for(i = 0; i < paraSize; i++) {
		resultPtr->weights[i]= (int*)malloc(paraSize * sizeof(int));
		for(j=0; j<paraSize; j++){
			resultPtr->weights[i][j] = paraData[i][j];
		}//of for j
	}//of for i
	
	return resultPtr;
}//of initNet

/**
*The prim algorithm for spanning tree,or the Dijkstra algorithm for nearest path.
*@param paraAlgorithm 0 for Dijkstra,1 for Prim
*return The total cost of the tree.
*/

int dijkstraOrPrim(NetPtr paraPtr,int paraAlgorithm){
	int i,j,minDistance,tempBestNode,resultCost;
	int source = 0;
	int numNodes = paraPtr->numNodes;
	int *distanceArray =(int *) malloc(numNodes * sizeof(int));
	int *parentArray = (int*)malloc(numNodes *sizeof(int));
	//Essential boolean
	int *visitedArray =(int*)malloc(numNodes * sizeof(int));
	//step1.Initialize.Any node can be the source.

	for(i=0;i<numNodes;i++){
		distanceArray[i]=paraPtr->weights[source][i];
		parentArray[i] = source;
		visitedArray[i] = 0;
	}//of for i

	distanceArray[source] = 0;
	parentArray[source] = -1;
	visitedArray[source] = 1;

	//step2.Main loops.
	tempBestNode = -1;
	for(i=0;i<numNodes -1;i++){

	//step2.1 Find out the best next node.
	minDistance = MAX_DISTANCE;
	for(j=0;j<numNodes;j++)	{
		//This node is visited.
		if(visitedArray[j]) {
			continue;
		}//of if
		
		if(minDistance > distanceArray[j]){
			minDistance = distanceArray[j];
			tempBestNode = j;
		}//of if
	}//of for j
	
	visitedArray[tempBestNode] = 1;

	//step2.2 Prepare for the next round.

	for(j = 0;j<numNodes;j++){
		//This node is visited.
		if(visitedArray[j]){
			continue;
		}//of if
		
		//This node canot be reaached.
		if(paraPtr->weights[tempBestNode][j] >= MAX_DISTANCE){
			continue;
		}//of if
		//Attention:the difference between Dijkstrs and algorithms.

		if(paraAlgorithm == 0){
			if(distanceArray[j] > distanceArray[tempBestNode] +paraPtr->weights[tempBestNode][j]){
				//change the distance.
				distanceArray[j] = distanceArray[tempBestNode] + paraPtr->weights[tempBestNode][j];
				//change the parent.
				parentArray[j] = tempBestNode; 
			}//of if
		}else{
			if(distanceArray[j]>paraPtr->weights[tempBestNode][j]){
				//change the distance
				distanceArray[j] = paraPtr->weights[tempBestNode][j];
				//cahnge the parent
				parentArray[j] =tempBestNode; 
			}//of if
		}//of if
	}//of for j
 }//of for i
        printf("the parent of each node:");
        for(i=0;i<numNodes;i++) {
        	printf("%d ,",parentArray[i]);
		}//of for i
		
		if(paraAlgorithm ==0){
			printf("From node 0,path length to all nodes are:");
			for(i=0;i<numNodes;i++){
				printf("%d (%d),",i,distanceArray[i]);
			}//of for i
		}else{
			resultCost = 0;
			for(i=0;i<numNodes;i++) {
				resultCost +=distanceArray[i];
				printf("cost of node %d is %d,total = %d\r\n",i,distanceArray[i],resultCost);
			}//of for i
			printf("Finaly ,the total cost is %d.\r\n",resultCost);
		}//of if
		
		//step3.output for debug.
		printf("\r\n") ;
		return resultCost;
}//of dijkstrsOrPrim

/**
*Construct a sample net.
*revised from testGraphTranverse
*/

NetPtr constructSampleNet() {
	int i,j;
	int myGraph[6][6]={
		{0,6,1,5,0,0},
		{6,0,5,0,3,0},
	    {1,5,0,5,6,4},
	    {5,0,5,0,0,2},
	    {0,3,6,0,0,6},
	    {0,0,4,2,6,0}};
	    int **tempPtr;
	    int numNodes = 6;
	    printf("Preparing data\r\n");
	    tempPtr = (int**)malloc(numNodes * sizeof(int*));

		for(i=0;i<numNodes;i++) {
			tempPtr[i] = (int*)malloc(sizeof(int));
		}//of for i

		for(i=0;i<numNodes;i++){
			for(j=0;j<numNodes;j++){
				if(myGraph[i][j] == 0){
					tempPtr[i][j] =MAX_DISTANCE;
				}else{
					tempPtr[i][j] =myGraph[i][j];
				}//of if
			}//of for j
		}//of for i

		printf("Data ready\r\n");
		NetPtr resultNetPtr =initNet(numNodes,tempPtr);
		return resultNetPtr;
}//of constructSampleNet

/**
*Test the prim algorithm.
*/

void testPrim(){
	NetPtr tempNetPtr=constructSampleNet() ;
	printf("=====Dijkstra algorthm=====\r\n");
	dijkstraOrPrim(tempNetPtr,0);
	printf("=====Prim algorithm=====\r\n");
	dijkstraOrPrim(tempNetPtr,1);
}//of test prim


/**
*The entrnace
*/

int main() {
	testPrim();
	return 1;
}//of main

2.运行结果

6c47bbfcabb34508a87874703482f913.jpg

 3.小结

Prim算法和Dijkstra算法都是图论中的经典算法,主要用于解决图的最短路径问题,但它们的应用场景和目标有所不同。

 

Prim算法是用来寻找加权连通图中的最小生成树(Minimum Spanning Tree, MST)的算法之一。最小生成树是指一棵包含所有顶点且边的权重之和最小的树。

基本思想:

1)初始化:从图中任选一个顶点开始,将其加入到已选择顶点集合中。

2)迭代扩展:在每一步中,选择一个连接已选择顶点集合与未选择顶点集合的最小权重边,将这条边的另一端点加入已选择顶点集合。

3)重复步骤2),直到所有顶点都被加入到已选择顶点集合中,此时得到的边集即为最小生成树的边集。

适用情况:加权连通无向图。

复杂度:使用优先队列优化后,时间复杂度可以达到O(ElogV),其中E是边的数量,V是顶点的数量。

 

Dijkstra算法

目标: Dijkstra算法用于计算加权图中,从单一源点到其余各顶点的最短路径。

基本思想:

1)初始化:为每个顶点分配一个距离值,源点的距离设为0,其他所有顶点的距离设为无穷大。创建一个未访问顶点集合。

2)选择顶点:从未访问顶点中选择距离最小的顶点,访问并标记为已访问。

3)更新邻居距离: 对于当前顶点的所有未访问邻居,如果通过当前顶点到达该邻居的距离比已知的最短距离要短,则更新该邻居的最短距离。

4)重复步骤2)和3),直到所有顶点都被访问过或找到目标顶点为止。

适用情况: 加权连通图,可以是有向也可以是无向,但要求边的权重非负。

复杂度:使用优先队列优化后,时间复杂度同样为O(ElogV)。

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值