Dijkstra算法:
Dijkstra算法可以将所有顶点分成三个集合,源点集合{A},已经计算出最短路径的顶点集合U,和未计算出最短路径的顶点集合.
1.初始状态时候,集合U为空,集合T等于V-{A},并初始化设置集合T中顶点的当前最短路径.
2.选取集合T中路径长度最短的元素加入到集合U中.
3.更新集合T中的元素对应的当前最短距离.此时集合T中的元素对应的路径,总是源点A经过集合U中的某些顶点(或者没有经过),到达集合T中的顶点时的最短路径.
4.如果T不为空,回到2,否则结束.
注意:
1.在集合T中路径最短的点,该点记录的路径就是A到达该点的最短路径.此时把该点从集合T中移到集合U中.这就是为什么第3步中,要从集合T选取的路径最短的节点的原因.
2.为什么集合T中路径最短的点,该点记录的路径就是A到达该点的最短路径?
反证法:把集合T中路径最短的点记作B,假设B点记录的路径不是A到B的最短路径,那么必定有一条路径比此时的路径小,如果该条路径直接由A到达B,那么此后对该顶点所记录的距离就不会进行更新.如果顶点A途经某个节点到达B.我们把该节点记为C,易知节点C必定不在集合U中(如果在集合U中,那么在第3步更新集合T的时候,就不是使得B点记录的路径变大为当前记录的路径.),而且不在集合T中(因为若在集合T中,顶点C记录的距离一定比B的小,就会优先选择顶点C,而不会选择顶点B),所以顶点C不在T中,不在U中,即不存在顶点c.而且B所记录的路径就是最短路径.
在编程过程中出现的错误:
循环忘了后移导致死循环.
#include<iostream>
#include<deque>
#include<queue>
usingnamespace std;
#defineVexNum 5
#defineVEXMAX 100000
typedefchar VextexType;
typedefint EdgeType;
structEdgeNode;
structEdgeNode {
VextexType HeadName;
VextexType TailName;
EdgeType weight;
EdgeNode *VexOut;
EdgeNode *VexIn;
bool operator < (const EdgeNode&node)const {
return weight > node.weight;
}
};
structvexWeight{
char name;
int pathWeight;
char path[VexNum+1];
};
typedefstruct
{
VextexType name;
EdgeNode *VexOutlink;
EdgeNode *VexInlink;
}VexNode;
VexNodeadjList[VexNum];
boolvisit[VexNum];
intfather[VexNum];
intrank_set[VexNum];
voidcreatGraph()
{
VextexType vextemp;
EdgeType edgetemp;
char a[]={'A','B','C','D','E'};
int b[] = { 0, 1, 0, 1, 0,
0, 0, 6, 2, 0,
0, 0, 0, 0, 2,
0 ,1, 0, 0, 1,
0, 0, 1, 0, 0};
//input n vextex
for ( int i=0; i<VexNum ; ++i ){
// cin>>vextemp;
vextemp = a[i];
adjList[i].name = vextemp;
adjList[i].VexOutlink = NULL;
adjList[i].VexInlink = NULL;
}
for ( int i=0; i<VexNum*VexNum; ++i ){
//cin>>edgetemp;
edgetemp = b[i];
if ( edgetemp==0 ){
continue;
}
EdgeNode *pEdge = new EdgeNode;
pEdge->HeadName =adjList[i/VexNum].name;
pEdge->TailName =adjList[i%VexNum].name;
pEdge->weight = edgetemp;
pEdge->VexOut = adjList[i/VexNum].VexOutlink;
if ( pEdge->VexOut ){
while ( pEdge->VexOut->VexOut){
pEdge->VexOut=pEdge->VexOut->VexOut;
}
pEdge->VexOut->VexOut =pEdge;
pEdge->VexOut=NULL;
} else {
adjList[i/VexNum].VexOutlink =pEdge;
pEdge->VexOut = NULL;
}
}
for ( int i=0 ;i<VexNum ;++i ){
EdgeNode **pInLink =&adjList[i].VexInlink;
for ( int j=0; j<VexNum; ++j ){
if ( i==j ){
continue;
}
EdgeNode *p =adjList[j].VexOutlink;
while ( p ){
if ( p->TailName !=adjList[i].name ){
p = p->VexOut;
continue;
}
*pInLink = p;
pInLink = &p->VexIn;
p = p->VexOut;
}
}
*pInLink = NULL;
}
}
voiddestroyGrape()
{
for ( int i=0; i<VexNum ;++i ){
EdgeNode *p = adjList[i].VexOutlink;
EdgeNode *q;
while ( p ){
q = p;
p = p->VexOut;
delete q;
}
}
}
voidprintGrape()
{
for ( int i=0; i<VexNum; ++i ){
cout<<adjList[i].name<<"-->";
EdgeNode *p = adjList[i].VexOutlink;
while ( p ){
cout<<"("<<p->HeadName<<","<<p->TailName<<","<<p->weight<<")";
p = p->VexOut;
}
cout<<endl;
p = adjList[i].VexInlink;
cout<<adjList[i].name<<"-->";
while ( p ){
cout<<"("<<p->HeadName<<","<<p->TailName<<","<<p->weight<<")";
p = p->VexIn;
}
cout<<endl;
}
}
voidDijsktra()
{
vexWeight vexwe[VexNum];
EdgeNode *p = NULL;
vexWeight vexTemp ;
char bitMap = 0;
for ( int i=0; i<VexNum; ++i ){
vexwe[i].pathWeight = VEXMAX;
vexwe[i].path[0]='A';
vexwe[i].name = 'A'+i;
for ( int j=1; j<VexNum+1; ++j ){
vexwe[i].path[j]=0;
}
}
p = adjList[0].VexOutlink;
while ( p ){
vexwe[p->TailName-'A'].pathWeight=p->weight;
vexwe[p->TailName-'A'].path[1] =p->TailName;
p = p->VexOut;
}
for ( int i=1; i<VexNum; ++i ){
int currentWeight = VEXMAX;
int vexPos = 0;
for ( int k=1; k<VexNum; ++k ){
if ( ( bitMap & 1<<k)
|| vexwe[k].pathWeight >=currentWeight ){
continue;
}
currentWeight =vexwe[k].pathWeight;
vexPos = k;
}
if ( vexPos == 0 ||vexwe[vexPos].pathWeight == VEXMAX ){
cout<<"error"<<endl;
return ;
}
bitMap |= 1<<vexPos;
p = adjList[vexPos].VexOutlink;
while ( p ){
int vexPosExtern =p->TailName-'A';
int externWeight = currentWeight + p->weight;
if ( ( bitMap &1<<vexPosExtern )
|| externWeight >=vexwe[vexPosExtern].pathWeight){
p = p->VexOut;
continue;
}
vexwe[vexPosExtern].pathWeight= externWeight;
int j=0;
while ( vexwe[vexPos].path[j] ){
vexwe[vexPosExtern].path[j] =vexwe[vexPos].path[j];
++j;
}
vexwe[vexPosExtern].path[j] =vexwe[vexPosExtern].name;
p = p->VexOut;
}
}
for ( int i =1; i<VexNum; ++i ){
cout<<vexwe[i].path<<endl;
}
}
int main()
{
creatGraph();
printGrape();
Dijsktra();
destroyGrape();
}
input数据:
结果: