最短路径 Dijkstra算法
来源:互联网 发布:软件服务商 编辑:程序博客网 时间:2024/06/16 19:16
斗争了整整三天,终于实现了Dijkstra算法的第一个版本。
这次是用C++实现的,顺道集成了BFS与DFS。
这次的代码质量不高,就只发发代码和测试结果得了,下次完善代码之后,写一个篇专门的博文发上来
以下是测试
测试用图1:
测试结果1:
测试用图2:
测试结果2:
接下来是代码
注释太多了,凑活着看吧
/*名称:图的最短路径---Dijkstra算法的实现与应用描述:主体写为类的形式,基本数据成员设定为private权限,而相关的成员函数设定为public权限主要的成员函数有:图的构造函数(用于图的初始化,输入基本信息,初始化邻接矩阵)、图的矩阵的打印、DFS、BFS、Dijkstra算法、以及一些相应的辅助函数其中BFS需要的队列的及函出队入队数单独写作一个类*/#include<iostream>#include<string>using namespace std;#define MAX 100 //定义最大顶点数int Infinite=2000000000;//定义无限 用于描述不连同的边typedef int Vertex; //用整型描述顶点typedef int Edge; //用整型描述边enum GrapheType{ DG, UDG, DN, UDN };//用于描述图的种类 有向图/无向图 有向网/无向网,本例默认研究有向的连通图//队列类,在图的BFS中会用到class Queue//这是一个不循环的队列{public: Vertex array[MAX]; Vertex Front, Last;//public: Queue() { Front = 0; Last = 0; } ~Queue(){}; //入队函数 void In_Queue(Vertex Item) { if (Last != MAX) array[Last++] = Item; else cout << "队列已满" << endl; } //出队函数 int De_Queue() { if (Front != Last) return array[Front++]; else cout << "队列为空" << endl; } //判断队列是否为空 bool Is_Empty() { if (Front == Last) return true; else return false; }};//visited用于记录节点是否被访问int visited[MAX];//重置访问结果void Re_set(){ for (int i = 0; i < MAX; i++) visited[i] = 0;}//图类class MapGraphe {private: int Number_of_Vertex; //顶点的数量 int Number_of_Edges; //边的数量 Vertex Vertices[MAX]; //用于记录顶点 Edge Edges[MAX][MAX];//用于记录顶点互相之间的边的情况 GrapheType Type; //用于描述图的类型public: //创建并初始化整个图 void Creat_Map() { cout << "输入顶点的数量(所有的顶点默认从0开始编号)" << endl;;//先输入顶点的信息 cin >> Number_of_Vertex; for (int i = 0; i < Number_of_Vertex; i++) { Vertices[i] = i; } for (int i = 0; i < Number_of_Vertex; i++)//初始化邻接矩阵 for (int j = 0; j < Number_of_Vertex; j++) { if (i == j)//对角线的上表示顶点,用零表示 Edges[i][j] = 0; else Edges[i][j] = Infinite;//初始化默认没有边连通 } cout << "输入边的总数" << endl;//再输入边的信息 cin >> Number_of_Edges; cout << "输入时按照以下格式:起点 终点 路径长度(请正确输入,错了我可不知道会发生什么)" << endl; for (int i = 0; i < Number_of_Edges; i++) { int start, end, cost; cin >> start >> end >> cost; Edges[start][end] = cost;//代表start-->end这条路径的长度是cost,而end-->start默认是infinite,即不连通的 } } //图的矩阵的打印 void Matrix() { for (int i = 0; i < Number_of_Vertex; i++) { cout << endl; for (int j = 0; j < Number_of_Vertex; j++) { if (Edges[i][j] == Infinite) cout << 'U' << " "; else cout<<Edges[i][j] << " "; } } } //DFS void Depth_First_Search(Vertex Vertex_name) { int i; for (i = 0; i < Number_of_Vertex; i++)//先查找传入的节点是否存在 { if (Vertex_name == Vertices[i])//存在则直接break break; } if (i == Number_of_Vertex)//不存在则return { cout << "没有找到该顶点" << endl; return; } visited[Vertex_name] = 1; cout <<Vertex_name<< " ";//找到该顶点后输出该顶点 for (i = 0; i < Number_of_Vertex; i++) { if (i == Vertex_name) continue; if (Edges[Vertex_name][i] != Infinite) { if ( visited[i]==0 )//递归遍历与之连同且未被访问过的点 Depth_First_Search(i); } } } //BFS void Breadth_First_Serach(Vertex Vertex_name) { int i; for (i = 0; i < Number_of_Vertex; i++)//先查找传入的节点是否存在 { if (Vertex_name == Vertices[i])//存在则直接break break; } if (i == Number_of_Vertex)//不存在则return { cout << "没有找到该顶点" << endl; return; } Queue queue;//创建队列 queue.In_Queue(Vertex_name);//将第一个顶点入队 while (!queue.Is_Empty()) { int De_Queue_Item = queue.De_Queue();//将最前面的节点出队,打印并查找与之相连的顶点 if (visited[De_Queue_Item] == 1)//如果出队的节点已经访问过,进入下一次循环,再次出队元素 continue; cout << De_Queue_Item << " "; visited[De_Queue_Item] = 1;//访问过后,将之设置为已访问的状态 for (i = 0; i < Number_of_Vertex; i++) { if (i == De_Queue_Item ) continue; if (Edges[De_Queue_Item][i] != Infinite) queue.In_Queue(i); } } } //(辅助函数) Judge_Dijkstra : 判断是否全部顶点求出距离 bool Judge_Dijkstra(Vertex U[]) { int Invaild = -1;//查找非无效点来判断是否完全被纳入 for (int i = 0; i < Number_of_Vertex; i++) { if (U[i] != Invaild )//表示如果U中还有除出发点以外的任何顶点存在,则继续迭代 return 1; } return 0;//表示所有顶点已被纳入 } //(辅助函数) Find_Min : 找到集合中最小元素的 int Find_Min(Vertex U[]) { int Min = Infinite; for (int i = 0; i < Number_of_Vertex; i++) { if (U[i] < Min && U[i]>0) { Min = U[i]; } } return Min; } //(辅助函数) Find_Index_of_Min : 找到集合中最小元素在数组中的下标 int Find_Index_of_Min(Vertex U[],Vertex Min) { for (int i = 0; i < Number_of_Vertex; i++) { if (U[i] == Min) return i; } } //Dijkstra void Dijkstra(Vertex First_Vertex) { int Invaild = -1;//用于描述U中的以加入S的无效顶点 Vertex temp_Vertex = First_Vertex;//每次迭代用的点 Vertex S[MAX];//S代表已查找到指定顶点的最短路径的集合 Vertex U[MAX];//U代表尚未纳入集合的点 for (int i = 0; i < Number_of_Vertex; i++) { U[i] = Infinite;//初始化两个集合,默认除出发点以外的所有顶点都未被纳入集合 S[i] = Infinite;//默认所有顶点的距离都未被确定 } S[First_Vertex] = 0;//初始顶点到自己的距离为0 U[First_Vertex] = Invaild;//初始顶点在U中是无效点 do//一旦有顶点未被纳入,就继续迭代 { for (int i = 0; i < Number_of_Edges; i++) { if (temp_Vertex == i)//不能与自身比较,跳过 continue; if (Edges[temp_Vertex][i] != Infinite)//找到可以连接的点 if (U[i]>Edges[temp_Vertex][i] + S[temp_Vertex])//如果这个顶点的距离比原来U中小,则更新 U[i] = Edges[temp_Vertex][i] + S[temp_Vertex]; } Vertex Min = Find_Min(U);//找到集合中最小的元素 Vertex Index_of_Min = Find_Index_of_Min(U, Min);//找到集合中最小的元素在数组中的下标 S[Index_of_Min] = Min;//将找到最小元素加入集合中 U[Index_of_Min] = Invaild;//将这个顶点从U中删除掉 temp_Vertex = Index_of_Min;//以被删除的顶点进行考虑,更新到其它点的距离 for (int i = 0; i < Number_of_Vertex; i++)//新加入顶点之后,对到其它顶点的距离进行更新 { if (S[i]==0 && S[i]==Infinite)//跳过出发点和已经纳入S的点 continue; if (S[i] == Infinite)//并且这个节点并未纳入到S中 { int Path_length = Edges[Index_of_Min][i] + S[Index_of_Min];//计算出其距离出发点的距离 if (Path_length < U[i])//如果这个距离小于原本的连同距离,则更新 U[i]=Path_length; } } } while (Judge_Dijkstra(U)); //结束之后输出各点到出发点的最短距离 for (int i = 0; i < Number_of_Vertex; i++) { cout << "顶点标号" << i << "到顶点的距离" << S[i] << endl; } }};//一个输入提示菜单void list(){ cout << "\n1.打印矩阵 "<< "2.DFS " << "3.BFS " <<"4.求最短路径 " <<"5.退出 :";}int main(){ int i=0,j; MapGraphe Map; Map.Creat_Map(); while (i != 4) { list(); cin >> i; switch (i) { case 1: Map.Matrix(); break; case 2: cout << "输入DFS的第一个顶点:"; cin >> j; Map.Depth_First_Search(j); Re_set(); break; case 3: cout << "输入BFS的第一个顶点:"; cin >> j; Map.Breadth_First_Serach(j); Re_set(); break; case 4:cout << "输入出发点的标号:"; cin >> j; Map.Dijkstra(j); continue; break; case 5:return 0;break; default:continue;break; } } return 0;}
0 0
- DIJKSTRA最短路径算法
- 最短路径算法-dijkstra
- dijkstra最短路径算法
- 最短路径 Dijkstra算法
- 最短路径(Dijkstra算法)
- 最短路径Dijkstra算法
- 最短路径 Dijkstra算法
- Dijkstra最短路径算法
- 最短路径dijkstra算法
- 最短路径 dijkstra算法
- 最短路径Dijkstra 算法
- 最短路径 (Dijkstra算法)
- Dijkstra最短路径算法
- 最短路径(Dijkstra算法)
- 最短路径--Dijkstra算法
- Dijkstra最短路径算法
- Dijkstra最短路径算法
- Dijkstra最短路径算法
- EditText有内容时显示清空按钮,无内容时不显示
- GPUImge
- 技术演绎之 [ java ] java标识符
- 百度地图删除标尺,logo,缩放按钮
- SAP Batch Job 备注
- 最短路径 Dijkstra算法
- vs2012 error c4996: This function or variable may be unsafe
- 关于Android 和 JS 交互时调用不成功的问题
- C# WinForm捕获未处理的异常实例解析
- opencv调用笔记本摄像头程序
- LeetCode_44---Wildcard Matching
- Android studio 重置 DDMS面板布局
- 使用SNMP++开发电信设备网管之二:SNMP++库用法
- Hihocoder 计数