数据结构_图_最短路径_狄杰斯特拉(Dijkstra)算法

来源:互联网 发布:插手 子女 婚姻 知乎 编辑:程序博客网 时间:2024/05/16 05:31

此算法没有采用《数据结构C语言版》中的存储结构,而是采用邻接表的方法存储图,经过改进,还能输出最短路径。



"Dijkstra.h"


#include<iostream>using namespace std;#define MAX_VEX_NUM 20#define INFINITY INT_MAX#define CANTFIND -1class Path//记录源点到每一个点的路径{public:Path();int pathnode;Path *next;};Path::Path(){pathnode=0;next=NULL;}class NextNode//邻接表存储以某节点为尾的弧的相关信息{public:NextNode();int nextvex;//顶点编号int weight;//弧上的权值NextNode *next;//下一个节点的指针};NextNode::NextNode(){nextvex=weight=0;next=NULL;}class VexNode//顶点相关信息{public:VexNode();char name;//顶点名称bool choose;//标示此节点标示的最短路径是否已经被选择int dist;//此节点当前存放的最短路径NextNode *firstnext;Path *path;};VexNode::VexNode(){choose=false;dist=INFINITY;firstnext=NULL;path=NULL;}class VexBox//顶点集合{public:VexBox();int vexnum;//定点数目VexNode vexbox[MAX_VEX_NUM];//顶点集合};VexBox::VexBox(){vexnum=0;}class ShortestPath_DIJ{public:void ShortestPath();//接口函数private:void GetVex();//得到顶点信息void GetArc();//得到弧的相关信息void GetShortestPath();//得到最短路径void PrintShortestPath();//打印最短路径int GetShortestNode();//得到dist最小的节点void UpdatePath(int,int);//更新路径void ReMove(Path *);//销毁原路径VexBox v;//顶点集合int sourse;};void ShortestPath_DIJ::ShortestPath(){GetVex();//得到顶点信息GetArc();//得到弧的相关信息GetShortestPath();//得到最短路径PrintShortestPath();//打印最短路径}void ShortestPath_DIJ::GetVex()//得到顶点信息{cout<<"Please Input The Name Of Each Vertex :"<<endl<<endl;char name;while(cin>>name){v.vexbox[v.vexnum++].name=name;}cin.clear();}void ShortestPath_DIJ::GetArc()//得到弧的相关信息{cout<<"Please Input The Information Of Each Arc :"<<endl<<"tail head weight"<<endl;int tail,head,weight;NextNode *newnode,*p;while(cin>>tail>>head>>weight){newnode=new NextNode;newnode->nextvex=head;newnode->weight=weight;if((p=v.vexbox[tail].firstnext)==NULL){v.vexbox[tail].firstnext=newnode;}//ifelse{while(p->next!=NULL)p=p->next;p->next=newnode;}//else}//whilecin.clear();}int ShortestPath_DIJ::GetShortestNode()//得到dist最小的节点{int ans=CANTFIND,min=INT_MAX;for(int i=0;i<v.vexnum;i++){if(v.vexbox[i].choose==false&&v.vexbox[i].dist<min){min=v.vexbox[i].dist;ans=i;}//if}//forv.vexbox[ans].choose=true;//标记为已选择return ans;}void ShortestPath_DIJ::ReMove(Path *p)//销毁原路径{if(p->next!=NULL)ReMove(p->next);delete p;}void ShortestPath_DIJ::UpdatePath(int a,int b)//更新路径{Path *p,*pt,*newpath;ReMove(v.vexbox[b].path);newpath=new Path;newpath->pathnode=v.vexbox[a].path->pathnode;v.vexbox[b].path=newpath;p=v.vexbox[a].path->next;pt=v.vexbox[b].path;while(p!=NULL){newpath=new Path;newpath->pathnode=p->pathnode;pt->next=newpath;p=p->next;pt=pt->next;}}void ShortestPath_DIJ::GetShortestPath()//得到最短路径{Path *newpath,*pt;cout<<"Please Input The Sourse :"<<endl;while(cin>>sourse&&!(sourse<v.vexnum));//得到符合条件的源点cout<<v.vexbox[sourse].name<<" : Start"<<endl;v.vexbox[sourse].dist=0;//对源点的相关处理for(int i=0;i<v.vexnum;i++)//初始化路径{if(i!=sourse){newpath=new Path;newpath->pathnode=sourse;v.vexbox[i].path=newpath;}}NextNode *p;p=v.vexbox[sourse].firstnext;while(p!=NULL){newpath=new Path;newpath->pathnode=p->nextvex;v.vexbox[p->nextvex].path->next=newpath;v.vexbox[p->nextvex].dist=p->weight;p=p->next;}int ncase=v.vexnum-1;int node;while(ncase--)//处理源点到其他点的最短路径长度{node=GetShortestNode();//获得当前情况下未被选择的最短边if(node==CANTFIND)//控制跳出break;p=v.vexbox[node].firstnext;while(p!=NULL)//如有必要修改和该顶点相关的节点的Dist值{if(v.vexbox[node].dist+p->weight<v.vexbox[p->nextvex].dist){v.vexbox[p->nextvex].dist=v.vexbox[node].dist+p->weight;UpdatePath(node,p->nextvex);newpath=new Path;newpath->pathnode=p->nextvex;pt=v.vexbox[p->nextvex].path;while(pt->next!=NULL)pt=pt->next;pt->next=newpath;}p=p->next;}}}void ShortestPath_DIJ::PrintShortestPath()//打印最短路径{Path *p;for(int i=0;i<v.vexnum;i++){if(i!=sourse){p=v.vexbox[i].path;cout<<v.vexbox[i].name<<" : ";if(v.vexbox[i].dist==INFINITY)cout<<"∞"<<endl;else{cout<<v.vexbox[i].dist<<" Path :";//打印路径cout<<v.vexbox[p->pathnode].name;p=p->next;while(p!=NULL){cout<<"->"<<v.vexbox[p->pathnode].name;p=p->next;}cout<<endl;}}//if}//for}




"mian.cpp"



#include"Dijkstra.h"int main(){ShortestPath_DIJ d;d.ShortestPath();system("pause");}