图的最短路径dijkstra算法
2013-03-20 16:08
330 查看
想法是这样的:
1. 最开始要建立4个list,分别存储
a. 所有的Vertex: allVertex[]
b. 一个空的Vertex list: emptyVertex[]
c. 一个前缀表 previous list(用来回溯路径用): previous[]
d. 一个表示最短距离的表(就是表示某个点与0点的最短距离):
前两个list是用来辅助操作的,后2个表则是输出,通过后2个表我们能得到想要的一切结果。
因此我们的任务其实就是,最终把c。d两个表填充完毕即可。
2. 我们要做一个循环,循环次数为VertexMax次,因为如果是连通图,每次循环都能处理一个Vertex。
3. 第一次循环前我们把start这个vertex从allVertex表,移动到emptyVertex表。
4. 这样我们就需要遍历,与empty表所有vertex关联的每一条line。找出这些line中最短的一条。
5. 找到最短的这条line之后,更新一下previous表,previous[line->end] = start; 然后更新一下distances表, (distances[line->end]) 同 (distances[start] + line->weight)取最小值
6. 然后,line->end作为新的start,重新进入循环。。重复3-5步即可。
。。。
1. 最开始要建立4个list,分别存储
a. 所有的Vertex: allVertex[]
b. 一个空的Vertex list: emptyVertex[]
c. 一个前缀表 previous list(用来回溯路径用): previous[]
d. 一个表示最短距离的表(就是表示某个点与0点的最短距离):
前两个list是用来辅助操作的,后2个表则是输出,通过后2个表我们能得到想要的一切结果。
因此我们的任务其实就是,最终把c。d两个表填充完毕即可。
2. 我们要做一个循环,循环次数为VertexMax次,因为如果是连通图,每次循环都能处理一个Vertex。
3. 第一次循环前我们把start这个vertex从allVertex表,移动到emptyVertex表。
4. 这样我们就需要遍历,与empty表所有vertex关联的每一条line。找出这些line中最短的一条。
5. 找到最短的这条line之后,更新一下previous表,previous[line->end] = start; 然后更新一下distances表, (distances[line->end]) 同 (distances[start] + line->weight)取最小值
6. 然后,line->end作为新的start,重新进入循环。。重复3-5步即可。
#include <iostream> using namespace std; const int MAX_VERTEX = 5;//图的顶点数 const int MAX_INT = 0x7fffffff;//4字节的整数 const int MIN_INT = 0xffffffff;//4字节的整数 enum Kind{NG, DG};//无向图,有向图 Kind k = NG;//图的种类 int graph[MAX_VERTEX][MAX_VERTEX];//图 int emptyVertex[MAX_VERTEX];//空的Vertex集合 int allVertex[MAX_VERTEX];//当前Vertex集合 int previous[MAX_VERTEX];//前缀 int distances[MAX_VERTEX];//distance void printGraph(){//打印图 cout<<"-----------begin-------------"<<endl; for(int i = 0; i < MAX_VERTEX; i++){ for(int j = 0; j < MAX_VERTEX; j++){ if(graph[i][j] < MAX_INT){ cout<<graph[i][j]<<"\t"; }else{ cout<<"∞\t"; } } cout<<"\n\v"; } cout<<"-----------end-------------"<<endl; } void printArr(int *arr, int len){//打印数组 for(int i = 0; i < len; i++){ if(arr[i] >= MAX_INT){ cout<<"∞\t"; }else{ cout<<arr[i]<<"\t"; } } cout<<endl; } void printSituation(){//打印整个结构的各个数据部分。 cout<<"[[======================================"<<endl; //cout<<"graph:\n"; //printGraph(); cout<<"allVertex:\n"; printArr(allVertex, MAX_VERTEX); cout<<"emptyVertex:\n"; printArr(emptyVertex, MAX_VERTEX); cout<<"previous:\n"; printArr(previous, MAX_VERTEX); cout<<"distances:\n"; printArr(distances, MAX_VERTEX); cout<<"======================================]]"<<endl; } void init(){//初始化 for(int i = 0; i < MAX_VERTEX; i++){ emptyVertex[i] = MAX_INT; allVertex[i] = i; previous[i] = MAX_INT; distances[i] = MAX_INT; for(int j = 0; j < MAX_VERTEX; j++){ graph[i][j] = MAX_INT; } } distances[0] = 0; } void addLine(int start, int end, int weight){//增加一条line if(start >= MAX_VERTEX || end >= MAX_VERTEX) return; graph[start][end] = weight; if(k == NG){ graph[end][start] = weight; } } void rmLine(int start, int end){//移除一条line if(start >= MAX_VERTEX || end >= MAX_VERTEX) return; graph[start][end] = MAX_INT; if(k == NG){ graph[end][start] = MAX_INT; } } void dijkstra(){ int start = 0; int emptyI = 0;//emptyVertex数组的下标 int numHandled = 0;//每次循环都能处理一个vertex,因此需要循环MAX_VERTEX次。 while(numHandled < MAX_VERTEX){ //1. 把start从allVertex中取出,放入emptyVertex中 emptyVertex[emptyI++] = allVertex[start]; allVertex[start] = MAX_INT; //2. 找出 已经加入到 empty中的所有点上 的所有的line, 选出其中最短的一条,其end点作为下一次访问的起始点。 //3. 根据这些line重新计算distances, 更新distances表--同时更新前缀表,前缀表是随着distances表变化的。 int shortestWeight = MAX_INT; int shortestEnd = MIN_INT; for(int j = 0; j < MAX_VERTEX; j++){ int currentStart = emptyVertex[j]; if(currentStart < MAX_INT){//每一个在empty中的vertex都必须参加比较。在所有的这些vertex中关联的line中选一条 end 值不在empty中的最短的line。 for(int i = 0; i < MAX_VERTEX; i++){//i值表示 (currentStart -> i) 这条 line 的 end值 if(graph[currentStart][i] >= MAX_INT) {//如果这条line不存在,搜索下一条 continue; } else{ if(allVertex[i] != MAX_INT && shortestWeight > graph[currentStart][i]){//并且这条line不能是计算过的。如果合法,则比较当前最小的weight。 shortestWeight = graph[currentStart][i];//选中这条line。 shortestEnd = i;//记住这条line。 if(distances[i] >= MAX_INT){//调整distances和previous. distances[i] = graph[currentStart][i] + distances[currentStart]; previous[i] = currentStart; }else{ if(distances[currentStart] + graph[currentStart][i] < distances[i]){ distances[i] = distances[currentStart] + graph[currentStart][i]; previous[i] = currentStart; } } } } } } } //4. 把最短的line的end作为新的start重新循环, if(shortestEnd == MIN_INT){ cout<<"error!! shortestEnd == MIN_INT"<<endl; }else{ cout<<"&&shortest line "<<shortestEnd<<", shortestWeight = "<<shortestWeight<<endl; start = shortestEnd; } //5. numHandled++ numHandled++; printSituation(); } } int main(){ init(); /*addLine(0, 1, 5); addLine(1, 2, 7); addLine(1, 4, 5); addLine(2, 3, 8); addLine(2, 4, 9); addLine(2, 5, 7); addLine(3, 5, 5); addLine(4, 5, 15); addLine(4, 6, 6); addLine(5, 6, 8); addLine(5, 7, 9); addLine(6, 7, 11);*/ k = DG; addLine(0, 1, 10); addLine(0, 3, 30); addLine(0, 4, 100); addLine(1, 2, 50); addLine(2, 4, 10); addLine(3, 2, 20); addLine(3, 4, 60); dijkstra(); }
。。。
相关文章推荐
- 数据结构与算法--最短路径之Dijkstra算法
- 最短路径之Dijkstra算法详细讲解
- 单源最短路径算法--Dijkstra算法和Bellman-Ford算法
- 单源点最短路径----Dijkstra算法
- 单源最短路径复习--Dijkstra算法和Floyd算法
- HDOJ 2544 最短路(最短路径 dijkstra算法,SPFA邻接表实现,floyd算法)
- 最短路径 Dijkstra算法
- Dijkstra算法求最短路径
- 有向图某顶点到其他顶点最短路径的C程序实现代码(Dijkstra算法)
- 单源最短路径-Dijkstra算法 学习笔记
- Dijkstra算法(单源最短路径)
- 图结构练习——最短路径 dijkstra算法
- 最短路径—Dijkstra算法
- 最短路径算法—Dijkstra算法和BellmanFord算法
- 无向图的最短路径求解算法之——Dijkstra算法【转】
- dijkstra算法-最短路径(包含路径记录)
- hdu3790最短路径问题 (Dijkstra算法)
- 最短路径(dijkstra算法)
- 最短路径—Dijkstra算法和Floyd算法
- 最短路径(Dijkstra算法)