prime算法和dijkstra算法的主要区别,以及实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37373250/article/details/78924230


prime算法参考点击打开链接http://blog.csdn.net/yeruby/article/details/38615045

1. prime算法和dijkstra算法的主要区别

Dijkstra算法的对象无所谓是有向图还是无向图,它可以求单源最短路径(一个点到其余各点的最短路径),时间复杂度为O(n*n)。非常相似prime算法,只有一个区别,

核心思想就是更新连接路径时,prime中是跟踪接下来的结点到生成树中的最小交叉边,而dijkstra中是跟踪接下来的结点到

起点所有经过的结点的路径和,这样说不太好理解,

以下图举个例子(只分析v5):初始化后(以v1为起点),在prime中,v5原本连在v1上(v5路径长度为无穷),第一次更新路径时,v5连在v3上(v5路径长度为6),同样的条件下,在dijkstra中,v5原本连在v1上(v5路径长度为无穷)也变为连在v3上,可是路径长度变为7(1+6),这就是两者的区别了!



2. 代码实现

#include<iostream>
#include<fstream>
#define max 100
#define infinity 0x7fffffff
using namespace std;


struct MinPath
{
	int path;//该边所对应的起点(存放路径)
	double lowcost;//该边终点所对应的权值(存放路径长度)
	bool test;//判断该点是否已找到从起点到它的最短路径
};
class MGraph
{
public:
	MGraph();
	double Dijstra(int v);
	void dfspath(int i,int v);//回溯起点v到终点i的最短路径
	void PrintPath(int v);//打印起点v到各点的最短路径
private:
	int graph[max][max];
	int vexnum,edgenum;double sumcost;//分别为总结点数,总边数,最小路径权值和
	MinPath *minpath;
};

 MGraph::MGraph():sumcost(0)
{
	int i,j,lowcost;
	ifstream in("data.txt");
	if(!in.fail())
	{
	in>>vexnum>>edgenum;
	for( i=1;i<=vexnum;++i)
	{
		for(j=1;j<=vexnum;++j)
		{
			if(i==j)
			{
				graph[i][j]=0;
			}
			else
				graph[i][j]=infinity;
		}
	}
	for(int k=1;k<=edgenum;++k)//赋值有连接的边
	{
		in>>i>>j>>lowcost;
		graph[i][j]=graph[j][i]=lowcost;
	}
	}
	in.close();
}
double MGraph::Dijstra(int v)
{
	minpath=new MinPath[vexnum+1];
	for(int i=1;i<=vexnum;++i)
	{
		minpath[i].path=v;
		minpath[i].lowcost=graph[v][i];
		minpath[i].test=false;
	}
	minpath[v].test=true;
	for(int i=2;i<=vexnum;++i)//第一个点已加入,剩下还要加vexnum-1个
	{
		int minid=0;minpath[minid].lowcost=infinity;
		for(int j=1;j<=vexnum;++j)
		{
			if(!minpath[j].test&&minpath[minid].lowcost>minpath[j].lowcost)
				minid=j;
		}
		cout<<"V"<<v<<"-->V"<<minid<<"="<<minpath[minid].lowcost<<endl;
		sumcost+=minpath[minid].lowcost; minpath[minid].test=true;
		for(int j=1;j<=vexnum;++j)
		{
			if(!minpath[j].test&&minpath[minid].lowcost+graph[minid][j]<minpath[j].lowcost)
			{
				minpath[j].lowcost=minpath[minid].lowcost+graph[minid][j];
				minpath[j].path=minid;
			}
		}
	}
	return sumcost;
}
void MGraph::dfspath(int i,int v)
{
	if(v==i)
		return ;
	else
	{
		int j=i;
		i=minpath[i].path;//回溯,i是j前面一个数
		dfspath(i,v);
		if(v==i)
	           cout<<"V"<<i<<"-->V"<<j;
		else
		   cout<<"-->V"<<j;
		
	}
}
void MGraph::PrintPath(int v)
{
	for(int i=1;i<=vexnum;++i)
	{
		if(i!=v)
		{
			dfspath(i,v);
		    cout<<endl;
		}
	}
}
int main()
{
	MGraph mg;int v;
	cout<<"请输入起点序号v";
	cin>>v;
	cout << "最小权值和="<<mg.Dijstra(v)<<endl;
	cout<<"单源最短(完整)路径:"<<endl;
	mg.PrintPath(v);
	return 0;
}

强调一点,单源最短路径的输出用到了回溯的方法,从尾到头的输出很容易让人犯浑,主要就是搞清楚每次递归时的起点和终点就行!

3. 调试




Output :



猜你喜欢

转载自blog.csdn.net/qq_37373250/article/details/78924230
今日推荐