这是对两种数据结构的实现方式的具体的代码:
在看代码之前,需要了解什么时邻接矩阵和邻接表,请看别人写的博客:
https://blog.csdn.net/daocaoren_/article/details/98632474
对于Dijkstra算法的介绍就不介绍了,因为网上有很多
邻接矩阵的实现代码:
//假设:
//1.我们已经有了一个邻接矩阵的数据G,G[i][j]表示从顶点i到顶点j的距离
//2.我们从st顶点出发
//3.我们有vernum个顶点
//4.int dist[vernum]数组;dise[i]表示i顶点到Vs集合的距离;vs指的是已经遍历过的节点
//5.int used[vernum]数组;used[i]==1表示i顶点已经加入了vs集合;vs初始只有st节点
#define inf 999999
Dijkstra(Graphic G,int st)
{
//初始化
for(int i=0;i<vernum;++i)
{
used[i]=0; //初始时所有的顶点都没有加入VS集合
dist[i]=inf; //初始时所有的顶点到VS集合的距离都是无穷
if(dist[i]>G[st][i])
dist[i]=G[st][i]; //随便把源顶点可达的顶点距离更新
}
//开始加入第一个顶点(假设5)
used[st]=1;
dist[st]=0; //所有顶点到自身的距离都是0
//下面开始真正的算法核心
for(int i=0;i<vernum;++i) //遍历所有的顶点
{
//第一步:找到距离到集合vs最短的顶点
int pos=1; //记录距离到集合vs最短的顶点
int tmp_dist=inf;
for(int j=0;j<vernum;++j)
{
//找到一个顶点离vs集合最近
if(used[j]==0 && dist[j]<tmp_dist)
{
pos=j;
tmp_dist=dist[j];//记录这个顶点到VS的距离
}
}
//第二步:把找到的顶点加入vs中
used[pos]=1;
//第三步:更新未加入vs的顶点到vs集合的距离
for(int j=0;j<vernum;++j)
{
if(used[j]==0 && dist[j]>G[pos][j]+tmp_dist) //如果G[pos][j]==inf,那么将不会更新
dist[j]=G[pos][j]+tmp_dist;
}
}
}
邻接表的实现:
参考博客:
https://blog.csdn.net/m0_51657509/article/details/128068016
//假设:
//1.我们有邻接表L
//2.我们有dist[vernum],used[vernum]和上个例子的一样
//3.prev[vernum]矩阵,prev[i]表示i顶点的前一个顶点,可以用来打印路径
//4.st为开始顶点
//5.getdistance(L,st,end),表示邻接表中从st到end顶点的距离
#define inf 999999
Dijkstra(Adjlist &L,int st,vector<int>&dist,vector<int>&prev)
{
//初始化
for(int i=0;i<vernum;++i)
{
used[i]=0;
prev[i]=st; //一开始所有的顶点都以st为前顶点,即以st为出发点
dist[i]=getdistance(L,st,i);
}
//开始加入第一个顶点
used[st]=1
//下面开始真正的算法核心
for(int i=0;i<vernum;++i)
{
//第一步:找到距离到集合vs最短的顶点
int pos=1; //记录距离到集合vs最短的顶点
int tmp_dist=inf;
for(int j=0;j<vernum;++j)
{
//找到一个顶点离vs集合最近
if(used[j]==0 && dist[j]<tmp_dist)
{
pos=j;
tmp_dist=dist[j];//记录这个顶点到VS的距离
}
}
//第二步:把找到的顶点加入vs中
used[pos]=1;
//第三步:更新未加入vs的顶点到vs集合的距离
for(int j=0;j<vernum;++j)
{
if(used[j]==0 && dist[j]>getdistance(L,pos,j)+tmp_dist) //如果getdistance(L,pos,j)==inf,那么将不会更新
{
dist[j]=getdistance(L,pos,j)+tmp_dist;
prev[j]=pos; //说明顶点j可以由顶点pos到达
}
}
}
}
getdistance(Adjlist & L,int & st,int & end)
{
if(st==end)
return 0;
ArcNode* tmp = G.adjlist[st].firstedge;
while(tmp){
if(tmp->adjvex == end) return tmp->weight;
tmp = tmp->next;
}
return inf;
}
// 邻接表
struct ArcNode // 边信息
{
int adjvex;//有向边的 目标顶点 下标(从1开始)
int weight;//边的权值
struct ArcNode *next; //邻接表,指向下一个邻接边信息
};
struct VertexNode // 顶点
{
int vertex;//顶点下标(1 ~)
ArcNode *firstedge;// 有向边信息节点指针(源为vertex)
};
struct AdjList // 图
{
vector<VertexNode> adjlist;//顶点数组
int vexnum; //顶点数
int arcnum; //边数
};