大致过程:
设置一个weight[],path[],weight[i[表示当前已知的从源点到当前顶点i的最短路径长度,path[i]表示已知的从源点到顶点i的最短路径上,顶点i前顶点的下标,初始化为-1。
1.确定一个源点,设置为当前点,加入到集合中;
2.进入循环,找出与当前点相邻的顶点,重新计算源点到这些顶点的路径权值,更新weight [ ]和path [ ]数组;
3.选取weight[]中权值最小的有效路径(有效表示路径长度有效且该顶点尚未加入),将顶点加入到集合中,并设置为当前点,进入下次循环。
(1)设置0为源点, 找出相邻点重新计算路径,0->1:10 0->2: -1 0->3:30 0->4:100 , 显然0->1最短,1加入集合
(2)当前点为1,找出相邻点重新计算路径, 0->1: 10(已加入无效) 0->1->2: 60 0->3: 30 0->4:100 ,0->3最短,3加入集合
(3)当前点为3,找出相邻点重新计算路径, 0->1: 10(已加入无效)0->3->2: 50 0->3: 30 (已加入无效) 0->3->4: 90 , 0->3->2最短,2加入集合
(4)当前点为2,找出相邻点重新计算路径, 0->1: 10(已加入无效) 0->3->2: 50(已加入无效) 0->3: 30(已加入无效) 0->3->2->4: 60 ,0->3->2->4最短,4加入。
完毕。
Code:
void Dijkstra_adjacency_list(Graphics *gh)
{
//存储结构使用邻接表
bool joined[Maxsize];
int path[Maxsize]; //用于记录某一顶点的前一个点的下标
int weight[Maxsize]; //用于记录源点到当前顶点的权值
int startnode=0;
int currentnode=0;
for(int i=0;i<gh->Vcount;i++)
{
joined[i]=false;
weight[i]=-1;
path[i]=-1;
}
printf("选取源点为:%d\n",startnode);
for(int i=0;i<gh->Vcount-1;i++)
{
joined[currentnode]=true;
int length=0;
if(currentnode!=startnode)
length+=weight[currentnode];
EdgeNode *tempedge=gh->graph[currentnode]->link;
while(tempedge!=NULL)
{
int _length=length+tempedge->weight;
if(weight[tempedge->indx]==-1||length<weight[tempedge->indx])
{
weight[tempedge->indx]=_length;
path[tempedge->indx]=currentnode;
}
tempedge=tempedge->next;
}
int min=-1;
int minidx=0;
for(int j=0;j<gh->Vcount;j++)
{
if(weight[j]!=-1&&joined[j]!=true)
{
if(min==-1)
{
min=weight[j];
minidx=j;
}
else
{
if(weight[j]<min)
{
min=weight[j];
minidx=j;
}
}
}
}
printf("点:%d 加入,权值为:%d\n",minidx,min);
currentnode=minidx;
}
}
时间复杂度: O(n^2)