城市最短路径查询(C语言)
最短路径——dijkstra算法代码(c语言)
最短路径——dijkstra算法代码(c语⾔)最短路径问题看了王道的视频,感觉云⾥雾⾥的,所以写这个博客来加深理解。
(希望能在12点以前写完)()⼀、总体思想1.初始化三个辅助数组s[],dist[],path[]s[]:这个数组⽤来标记结点的访问与否,如果该结点被访问,则为1,如果该结点还没有访问,则为0;dist[]:这个数组⽤来记录当前从v到各个顶点的最短路径长度,算法的核⼼思想就是通过不断修改这个表实现; path[]:这个数组⽤来存放最短路径;2.遍历图,修改上⾯的各项数组,每次只找最短路径,直到遍历结束⼆、代码实现1void dijkstra(Graph G, int v)2 {3int s[G.vexnum];4int dist[G.vexnum];5int path[G.vexnum];6for(int i = 0; i < G.vexnum; i++)7 {8 s[i] = 0;9 dist[i] = G.edge[v][i];10if(G.edge[v][i] == max || G.edge[v][i] == 0)11 {12 path[i] = -1;13 }14else15 {16 path[i] = v;17 }18 s[v] = 1;19 }2021for(int i = 0; i < G.vexnum; i++)22 {23int min = max;24int u;25for(int j = 0; j < G.vexnum; j++)26 {27if(s[j] != 1 && dist[j] < min)28 {29 min = dist[j];30 u = j;31 }32 }33 s[u] = 1;34for(int j = 0; j < G.vexnum; j++)35 {36if(s[j] != 1 && dist[j] > dist[u] + G.edge[u][j])37 {38 dist[j] = dist[u] + G.edge[u][j];39 path[j] = u;40 }41 }42 }43 }三、代码解释先⾃⼰定义⼀个⽆穷⼤的值max#define max infdijkstra算法传⼊的两个参为图Graph G;起点结点 int v;⾸先我们需要三个辅助数组1int s[G.vexnum];//记录结点时是否被访问过,访问过为1,没有访问过为02int dist[G.vexnum];//记录当前的从v结点开始到各个结点的最短路径长度3int path[G.vexnum];//记录最短路径,存放的是该结点的上⼀个为最短路径的前驱结点初始化三个数组1for(int i = 0; i < G.vexnum; i++)2 {3 s[i] = 0;//⽬前每个结点均未被访问过,设为04 dist[i] = G.edge[v][i];//dist[]数组记录每个从v结点开到其他i结点边的长度(权值)5if(G.edge[v][i] == max || G.edge[v][i] == 0)6 {7 path[i] = -1;8 }//如果v到i不存在路径或者i就是v结点时,将path[i]设为-1,意为⽬前v结点不存在路径到i9else10 {11 path[i] = v;12 }//反之,若v到i存在路径,则v就是i的前驱结点,将path[i] = v13 s[v] = 1;//从遍历起点v开始,即已经访问过顶点s[v]=114 }开始遍历数组并且每次修改辅助数组以记录⽬前的情况,直⾄遍历结束1for(int i = 0; i < G.vexnum; i++)2 {3int min = max;//声明⼀个min = max⽤来每次记录这次遍历找到的最短路径的长度(权值)4int u;//声明u来记录这次历找到的最短路径的结点5for(int j = 0; j < G.vexnum; j++)//开始遍历找⽬前的最短路径6 {7if(s[j] != 1 && dist[j] < min)8 {9 min = dist[j];10 u = j;11 }//找出v到结点j的最短路径,并且记录下最短路径的结点u = j12 }13 s[u] = 1;//找到结点u,即已访问过u,s[u] = 114for(int j = 0; j < G.vexnum; j++)//开始遍历修改辅助数组的值15 {16if(s[j] != 1 && dist[j] > dist[u] + G.edge[u][j])17 {18 dist[j] = dist[u] + G.edge[u][j];19 path[j] = u;20 }//如果v→j的路径⽐v →u→j长,那么修改dist[j]的值为 dist[u] + G.edge[u][j],并且修改j的前驱结点为path[j] = u21 }22 }遍历结束后,数组dist[]就是存放了起点v开始到各个顶点的最短路径长度最短路径包含的结点就在path数组中例如我们得到如下的path[]数组1 path[0] = -1;//0到⾃⼰⽆前驱结点2 path[1] = 0;//1的前驱为结点0,0⽆前驱结点,即最短路径为0 →13 path[2] = 1;//2的前驱结为点1,1的前驱结点0,0⽆前驱结点,即最短路径为0 →1 →24 path[3] = 0;//3的前驱为结点0,0⽆前驱结点,即最短路径为0 →35 path[4] = 2;//4的前驱结为点2,2的前驱结为点1,1的前驱结点0,0⽆前驱结点,即最短路径为0 →1 →2 →4 dijkstra对于存在负权值的图不适⽤,明天再更新Floyd算法叭。
C语言迪杰斯特拉实现最短路径算法
C语言迪杰斯特拉实现最短路径算法迪杰斯特拉(Dijkstra)算法是一种用于在加权图中寻找从起点到终点的最短路径的算法。
它使用贪心算法的原理,每次选择权重最小的边进行扩展,直到找到终点或者无法扩展为止。
下面是C语言中迪杰斯特拉算法的实现。
```c#include <stdio.h>#include <stdbool.h>//定义图的最大节点数#define MAX_NODES 100//定义无穷大的距离#define INFINITY 9999//自定义图的结构体typedef structint distance[MAX_NODES][MAX_NODES]; // 节点间的距离int numNodes; // 节点数} Graph;//初始化图void initGraph(Graph* graph)int i, j;//设置所有节点之间的初始距离为无穷大for (i = 0; i < MAX_NODES; i++)for (j = 0; j < MAX_NODES; j++)graph->distance[i][j] = INFINITY;}}graph->numNodes = 0;//添加边到图void addEdge(Graph* graph, int source, int destination, int weight)graph->distance[source][destination] = weight;//打印最短路径void printShortestPath(int* parent, int node)if (parent[node] == -1)printf("%d ", node);return;}printShortestPath(parent, parent[node]);printf("%d ", node);//执行迪杰斯特拉算法void dijkstra(Graph* graph, int source, int destination) int i, j;//存储起点到各个节点的最短距离int dist[MAX_NODES];//存储当前节点的父节点int parent[MAX_NODES];//存储已访问的节点bool visited[MAX_NODES];//初始化所有节点的距离和父节点for (i = 0; i < graph->numNodes; i++)dist[i] = INFINITY;parent[i] = -1;visited[i] = false;}//设置起点的距离为0dist[source] = 0;//寻找最短路径for (i = 0; i < graph->numNodes - 1; i++)int minDist = INFINITY;int minNode = -1;//选择距离最小的节点作为当前节点for (j = 0; j < graph->numNodes; j++)if (!visited[j] && dist[j] < minDist)minDist = dist[j];minNode = j;}}//标记当前节点为已访问visited[minNode] = true;//更新最短距离和父节点for (j = 0; j < graph->numNodes; j++)if (!visited[j] && (dist[minNode] + graph->distance[minNode][j]) < dist[j])dist[j] = dist[minNode] + graph->distance[minNode][j];parent[j] = minNode;}}}//打印最短路径及距离printf("Shortest Path: ");printShortestPath(parent, destination);printf("\nShortest Distance: %d\n", dist[destination]); int maiGraph graph;int numNodes, numEdges, source, destination, weight;int i;//初始化图initGraph(&graph);//输入节点数和边数printf("Enter the number of nodes: ");scanf("%d", &numNodes);printf("Enter the number of edges: ");scanf("%d", &numEdges);graph.numNodes = numNodes;//输入边的信息for (i = 0; i < numEdges; i++)printf("Enter source, destination, and weight for edge %d: ", i + 1);scanf("%d %d %d", &source, &destination, &weight);addEdge(&graph, source, destination, weight);}//输入起点和终点printf("Enter the source node: ");scanf("%d", &source);printf("Enter the destination node: ");scanf("%d", &destination);//执行迪杰斯特拉算法dijkstra(&graph, source, destination);return 0;```上述代码中,我们首先定义了一个图的结构体,里面包括节点间的距离矩阵和节点数。
递归 最短路径 c语言
递归最短路径 in C语言一、什么是递归?递归是一种在算法中经常使用的方法,它允许函数调用自身。
递归的基本思想是将一个大问题划分为更小的子问题,通过解决这些子问题来解决原始问题。
在具体实现中,递归函数会不断调用自身,直到满足某个停止条件。
二、最短路径问题最短路径问题是在图论中非常重要的一个问题。
给定一个带权有向图或无向图,我们需要找到从起始点到目标点的最短路径,其中路径的长度定义为路径上所有边的权重之和。
三、递归解决最短路径问题在解决最短路径问题时,我们可以使用递归的方式来进行求解。
下面以有向无环图(DAG)为例进行说明。
1. 确定递归函数参数首先,我们需要确定递归函数的参数。
对于最短路径问题,递归函数需要知道当前所在的节点、目标节点以及当前路径的长度。
void findShortestPath(int curNode, int targetNode, int curLength);2. 设定停止条件在递归函数中,我们需要设定停止条件。
对于最短路径问题,停止条件可以是当前节点等于目标节点。
if (curNode == targetNode) {// 更新最短路径// 返回}3. 递归遍历邻接节点在递归函数中,我们需要遍历当前节点的所有邻接节点。
对于每个邻接节点,我们计算经过该节点的路径长度,并将其传递给下一层递归函数。
for (int i = 0; i < numNodes; i++) {if (graph[curNode][i] != INF) {int newPathLength = curLength + graph[curNode][i];findShortestPath(i, targetNode, newPathLength);}}4. 计算最短路径在递归函数的停止条件满足时,我们可以比较当前路径长度与已知的最短路径长度,并根据需要更新最短路径。
if (curNode == targetNode) {if (newPathLength < shortestLength) {// 更新最短路径}}5. 完整的递归解决方案综上所述,我们可以将递归解决最短路径问题的代码整合如下:#include <stdio.h>#define MAX_NODES 100#define INF 9999999int graph[MAX_NODES][MAX_NODES];int shortestPath[MAX_NODES];int shortestLength = INF;void findShortestPath(int curNode, int targetNode, int curLength) { if (curNode == targetNode) {if (curLength < shortestLength) {shortestLength = curLength;// 更新最短路径}return;}for (int i = 0; i < numNodes; i++) {if (graph[curNode][i] != INF) {int newPathLength = curLength + graph[curNode][i];findShortestPath(i, targetNode, newPathLength);}}}int main() {// 初始化图的边权,默认为INFfindShortestPath(startNode, targetNode, 0);// 输出最短路径和长度return 0;}四、总结递归是一种解决问题的有效方法,可以将复杂的问题简化为更小的子问题。
迪杰斯特拉算法c语言从某个源点到其余各顶点的最短路径 -回复
迪杰斯特拉算法c语言从某个源点到其余各顶点的最短路径-回复如何用C语言实现Dijkstra算法来找出从某个源点到其余各顶点的最短路径。
第一步:了解Dijkstra算法的基本原理Dijkstra算法是一种解决单源最短路径的经典算法。
它通过不断更新顶点的最短距离来求解从源点到其他顶点的最短路径。
算法基于一个贪心策略,每次选择当前最短距离的节点进行松弛操作,并标记该节点为已访问。
具体而言,算法包括以下步骤:1. 初始化,设置源点距离为0,其他所有节点的距离设为无穷大。
2. 选择距离源点最近的节点作为当前节点,并将它标记为已访问。
3. 遍历当前节点的所有邻接节点,如果经过当前节点到达邻接节点的距离比已知的最短距离小,则更新该邻接节点的最短距离。
4. 重复步骤2和3,直到所有节点都被标记为已访问,或者所有节点的最短距离都已确定。
第二步:创建数据结构来表示图为了实现Dijkstra算法,我们需要使用图数据结构来表示顶点和它们之间的边。
在C语言中,我们可以使用邻接矩阵和邻接链表两种方式来表示图。
邻接链表相对而言更加灵活和高效,因此我们选择使用邻接链表来表示图。
我们可以创建一个结构体来表示顶点,其中包含了顶点的索引、距离以及指向邻接节点的指针。
另外,我们还需要创建一个结构体来表示边,其中包含了边的权重和指向目标顶点的指针。
第三步:实现Dijkstra算法的主要函数首先,我们需要编写一个用于初始化图的函数,其中包括创建顶点和边的操作。
具体而言,我们可以使用邻接链表,将每个顶点作为链表的头节点,链表中的每个节点表示一个边,其中包含目标顶点的索引、权重和指向下一条边的指针。
接下来,我们需要编写一个用于查找当前最短距离的函数。
在该函数中,我们遍历所有未访问的节点,并返回距离源点最近的节点。
然后,我们需要编写一个用于更新当前节点的邻接节点的最短距离的函数。
在该函数中,我们遍历当前节点的邻接节点,如果通过当前节点到达邻接节点的距离比已知的最短距离小,则更新该邻接节点的最短距离。
单源最短路径dijkstra算法c语言
单源最短路径dijkstra算法c语言单源最短路径问题是图论中的经典问题之一,指的是在图中给定一个起始节点,求出该节点到其余所有节点之间的最短路径的算法。
其中,Dijkstra 算法是一种常用且高效的解决方案,可以在有向图或无向图中找到起始节点到其余所有节点的最短路径。
本文将逐步介绍Dijkstra算法的思想、原理以及C语言实现。
一、Dijkstra算法的思想和原理Dijkstra算法的思想基于贪心算法,通过逐步扩展当前已知路径长度最短的节点来逐步构建最短路径。
算法维护一个集合S,初始时集合S只包含起始节点。
然后,选择起始节点到集合S之外的节点的路径中长度最小的节点加入到集合S中,并更新其他节点的路径长度。
具体来说,算法分为以下几个步骤:1. 初始化:设置起始节点的路径长度为0,其他节点的路径长度为无穷大。
2. 选择最小节点:从集合S之外的节点中选择当前路径长度最短的节点加入到集合S中。
3. 更新路径长度:对于新加入的节点,更新与其相邻节点的路径长度(即加入新节点后的路径长度可能更小)。
4. 重复步骤2和3,直到集合S包含所有节点。
二、Dijkstra算法的C语言实现下面我们将逐步讲解如何用C语言实现Dijkstra算法。
1. 数据结构准备首先,我们需要准备一些数据结构来表示图。
我们可以使用邻接矩阵或邻接表来表示图。
这里,我们选择使用邻接矩阵的方式来表示权重。
我们需要定义一个二维数组来表示图的边权重,以及一个一维数组来表示起始节点到各个节点的路径长度。
c#define MAX_NODES 100int graph[MAX_NODES][MAX_NODES];int dist[MAX_NODES];2. 初始化在使用Dijkstra算法之前,我们需要对数据进行初始化,包括路径长度、边权重等信息。
cvoid initialize(int start_node, int num_nodes) {for (int i = 0; i < num_nodes; i++) {dist[i] = INT_MAX; 将所有节点的路径长度初始化为无穷大}dist[start_node] = 0; 起始节点到自身的路径长度为0初始化边权重for (int i = 0; i < num_nodes; i++) {for (int j = 0; j < num_nodes; j++) {if (i == j) {graph[i][j] = 0; 自身到自身的边权重为0} else {graph[i][j] = INT_MAX; 其他边权重初始化为无穷大}}}}3. 主要算法接下来是Dijkstra算法的主要逻辑。
C语言求解无向图顶点之间的所有最短路径
C语⾔求解⽆向图顶点之间的所有最短路径本⽂实例为⼤家分享了C语⾔求解⽆向图顶点之间的所有最短路径的具体代码,供⼤家参考,具体内容如下思路⼀:DFS,遇到终点之后进⾏记录辅助存储:std::vector<int> tempPath;std::vector<std::vector<int>> totalPath;实现://查找⽆向图的所有最短路径,直接dfs就可以解决了//记录保存这⾥⽤ vector<vector<int>> 插⼊失败,重新搞⼀下 OK// 时间复杂度 O(N + E)#include <iostream>#include <cstdio>#include <cstdlib>#include <vector>#include <set>#define MAX 10#define INF 999999int graph[MAX + 1][MAX + 1];int N, M; //node, edgeint nodeBook[MAX + 1];int minPath = INF;std::vector<int> pathNodeVec;std::vector<std::vector<int>> allShortVec;int startNode, endNode;void dfs(int i, int step){if (i == endNode) { //遇到终点,进⾏路径判定if (step < minPath) {std::cout << "step < minpath.., size = " << allShortVec.size() << std::endl;minPath = step;pathNodeVec.push_back(i);for (auto &elem : pathNodeVec)std::cout << elem << "\t";std::cout << std::endl;std::vector<int> tempVec = pathNodeVec;allShortVec.clear(); //清空allShortVec.push_back(tempVec); //存储pathNodeVec.pop_back();} else if (step == minPath) {std::cout << "step == minpath.., size = " << allShortVec.size() << std::endl;pathNodeVec.push_back(i);for (auto &elem : pathNodeVec)std::cout << elem << "\t";std::cout << std::endl;std::vector<int> tempVec = pathNodeVec;allShortVec.push_back(tempVec); //存储当前路径pathNodeVec.pop_back();} else { ;}return;}nodeBook[i] = 1;pathNodeVec.push_back(i);for (int x = 1; x <= N; x++) { //尝试所有可能性if (x == i)continue;if (nodeBook[x] == 1)continue;if (graph[i][x] == INF)continue;dfs(x, step + 1);}nodeBook[i] = 0;pathNodeVec.pop_back();return ;}int main(void){std::cin >> N >> M;for (int x = 1; x <= N; x++)nodeBook[x] = 0; //表⽰还没有访问for (int x = 1; x <= N; ++x)for (int y = 1; y <= N; ++y) {if (x == y)graph[x][y] = 0;elsegraph[x][y] = INF;}for (int i = 1; i <= M; ++i) {int tempX, tempY, tempWeight;std::cin >> tempX >> tempY >> tempWeight;graph[tempX][tempY] = tempWeight;}std::cout << "please input start node & end node :" << std::endl;std::cin >> startNode >> endNode;pathNodeVec.clear();allShortVec.clear();dfs(startNode, 0);std::cout << "all shortest path: \t";std::cout << "size = " << allShortVec.size() << std::endl;for (std::vector<std::vector<int>>::const_iterator it = allShortVec.begin(); it != allShortVec.end(); it++) {for (std::vector<int>::const_iterator it2 = (*it).begin(); it2 != (*it).end(); it2++)std::cout << (*it2) << "\t";std::cout << std::endl;}getchar();return 0;}时间分析:O(V + E)缺点:可能会爆栈,我这⾥算86W点+414W边直接爆,⼩的没问题。
c语言最短路径搜寻算法
c语言最短路径搜寻算法
C 语言最短路径搜寻算法常用于在网图中寻找两点之间的最短路径,其中网图的最短路径分为单源最短路径和多源最短路径。
以下是两种常见的最短路径搜寻算法:- Dijkstra 算法:从一个起始点出发,到达一个终点,通过对路径权值的累加,找到最短路径。
- Floyd 算法:对于网中的任意两个顶点来说,之间的最短路径不外乎有两种情况。
一种是直接从一个顶点到另一个顶点的边的权值;另一种是先经过若干个顶点,最终达到另一个顶点,期间经过的边的权值和。
这两种算法都可以用 C 语言实现,你可以根据具体需求选择合适的算法。
若你想了解更多关于最短路径搜寻算法的内容,可以继续向我提问。
c语言课程设计最短路径
c语言课程设计最短路径一、教学目标本节课的教学目标是让学生掌握C语言中最短路径算法的基本概念和实现方法。
具体包括以下三个方面:1.知识目标:使学生了解最短路径问题的背景和意义,理解Dijkstra算法和A*算法的原理,学会使用C语言实现最短路径算法。
2.技能目标:培养学生运用C语言解决实际问题的能力,提高学生的编程技巧和算法思维。
3.情感态度价值观目标:激发学生对计算机科学的兴趣,培养学生的创新精神和团队合作意识。
二、教学内容本节课的教学内容主要包括以下几个部分:1.最短路径问题的定义和意义:介绍最短路径问题的背景,让学生了解其在实际应用中的重要性。
2.Dijkstra算法:讲解Dijkstra算法的原理,演示算法的实现过程,让学生学会使用C语言实现Dijkstra算法。
3.A算法:介绍A算法的原理,讲解算法的优势和不足,让学生了解并掌握A*算法的实现方法。
4.算法优化:讨论如何优化算法,提高算法的效率,让学生学会在实际问题中灵活运用算法。
三、教学方法为了达到本节课的教学目标,将采用以下几种教学方法:1.讲授法:讲解最短路径问题的基本概念和算法原理,让学生掌握基本知识。
2.案例分析法:分析实际问题,让学生了解最短路径算法在实际应用中的价值。
3.实验法:让学生动手实践,学会使用C语言实现最短路径算法,提高编程能力。
4.讨论法:学生进行小组讨论,培养学生的团队合作意识和创新精神。
四、教学资源为了支持本节课的教学内容和教学方法,将准备以下教学资源:1.教材:《C语言程序设计》2.参考书:《数据结构与算法分析》3.多媒体资料:最短路径算法的动画演示4.实验设备:计算机、网络设备通过以上教学资源的支持,相信能够有效地帮助学生掌握最短路径算法,提高学生的编程能力。
五、教学评估为了全面、客观地评估学生在最短路径算法学习过程中的表现,将采用以下评估方式:1.平时表现:观察学生在课堂上的参与程度、提问回答和小组讨论的表现,以了解学生的学习态度和理解程度。
最短路径c语言
以下是使用Dijkstra算法实现最短路径的C语言代码示例:```c#include <stdio.h>#include <limits.h>#define V 5 // 顶点数int minDistance(int dist[], bool sptSet[]) {int min = INT_MAX, min_index;for (int v = 0; v < V; v++)if (sptSet[v] == false && dist[v] <= min)min = dist[v], min_index = v;return min_index;}void printSolution(int dist[]) {printf("Vertex \t Distance from Source\n");for (int i = 0; i < V; i++)printf("%d \t\t %d\n", i, dist[i]);}void dijkstra(int graph[V][V], int src) {int dist[V];bool sptSet[V];for (int i = 0; i < V; i++)dist[i] = INT_MAX, sptSet[i] = false;dist[src] = 0;for (int count = 0; count < V - 1; count++) {int u = minDistance(dist, sptSet);sptSet[u] = true;for (int v = 0; v < V; v++)if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v])dist[v] = dist[u] + graph[u][v];}printSolution(dist);}int main() {int graph[V][V] = { { 0, 4, 0, 0, 0 },{ 4, 0, 8, 0, 0 },{ 0, 8, 0, 7, 0 },{ 0, 0, 7, 0, 2 },{ 0, 0, 0, 2, 0 } };dijkstra(graph, 0);return 0;}```该代码使用邻接矩阵表示图,并使用Dijkstra算法计算从源顶点到其他顶点的最短路径。
6最短路径问题的几个算法
该算法的中心思想是:任意两点 i,j 间的最短距离(记为 Dij)会等于从 i 点出发到达 j 点的以任一点为中转点的所有可能的方案中, 距离最短的一个。 即: Dij=min(Dij,Dik+Dkj,……),1<=k<=5。 这样, 我所就找到了一个类似动态规划的表达式,只不过这里我们不把它当 作动态规划去处理, 而是做一个二维数组用以存放任意两点间的最短距离,利用 上述公式不断地对数组中的数据进行处理,直到各数据不再变化为止,这时即可 得到 A 到 E 的最短路径。 % X7 a5 a0 e2 `1 @! e0 F 算法如下: 1、 把上述邻接矩阵直接赋值给最短距离矩阵 D; - n9 o) r( a9 s% _- o7 } 2、 i=1; 0 c& w% z% m& w l4 x+ [% t 3、 j=1; 1 h* M" P8 N( G' O2 R 4、 repeat 5、 c=false; {用以判断第 6 步是否有某个 Dij 值被修改过} ) D, F6 F k( A 6、 Dij=min(Dij,Dik+Dkj,……), k=1 to 5 如果 Dij 被修改则 c=true 7、 I=I+1 8、 J=j+1 9、 Until not c 10、 打印 D15 $ j2 T, S) ?8 k0 b/ b6 Q& d! x 这种算法是产生这样一个过程: 不断地求一个数字最短距离矩阵中的数据的 值,而当所有数据都已经不能再变化时,就已经达到了目标的平衡状态,这时最 短距离矩阵中的值就是对应的两点间的最短距离。 , D8 Q& j" r8 C' A 五、动态规划 ! J O) z( i `; p- @ 动态规划算法已经成为了许多难题的首选算法, 只不过在很多的题目中动态规 划的算法表达式比较难找准, 而恰恰最短距离问题如果用动态规划算法考虑则可 以非常容易地找准那个算法表达式。 我们知道,动态规划算法与递归算法的不同之处在于它们的算法表达式: 递归:类似 f(n)=x1*f(n-1)+x2*f(n-2)………,即可以找到一个确定的关 系的表达式; 3 T; ]8 E% R" U7 ?6 G/ y c4 d( I; {% C 动态规划:类似 f(n)=min(f(n-1)+x1,f(n-2)+x2……),即我们无法找到确 定关系的表达式,只能找到这样一个不确定关系的表达式,f(n)的值是动态的, 随着 f(n-1),f(n-2)等值的改变而确定跟谁相关。 就本题来说,我们记 f(5)为 A 到 E 点的最短距离,则 f(4)为 A 到 D 点的最 短距离,f(1)为 A 到 A 点的最短距离(为 0) 。 于是,f(5)的值应该是所有与 E 点相邻的点的最短距离值再加上该点到 E 点的直接距离(dis 矩阵中的值)所得到的值中最小的一个。 我们可以得到这 样一个关系式: 7 j( {' m7 X* I5 \. t1 ]6 X f(5)=min(f(1)+dis(1,5), f(2)+dis(2,5), f(3)+dis(3,5), f(4)+dis(4,5)) 以此关系式作一个递归函数即可求得 A 到 E 点的最短距离。不过,为了节省 时间,我们可以把 f(1)-f(4)已经算得的结果保存起来给后面的递归直接调用, 这样就能节约大量的递归空间和时间,这对于数据量大时尤为重要。 关于最短路径问题还有以下几种算法: 一.最小生成树算法(破圈法)
贪心算法最短路径问题c语言代码
贪心算法最短路径问题c语言代码贪心算法最短路径问题C语言代码在计算机算法的领域中,贪心算法是一种常见的解决问题的方法。
贪心算法是一种寻找最优解的方法,就是在每个步骤中都采取最优的选择,这样每一步的最优解最终就可以得到整体的最优解。
在实际应用中,贪心算法通常被用于NP问题的解决,例如最短路径问题。
本文将介绍如何用C语言实现贪心算法解决最短路径问题。
1. 最短路径问题概述最短路径问题是一种图论问题,是指在一个有权重的有向图或无向图中,从一个指定的起点节点到达一个指定终点节点的最短路径问题。
在实际应用中,最短路径问题的应用非常广泛,例如地图导航、网络寻路、信息传递等等。
2. 贪心算法的原理贪心算法是一种自顶向下的设计方法,它主要依赖与一种贪心的选择方法。
在每个步骤中,都会选择能够最优化当前直接的步骤的答案。
因此,当遇到问题难以确定最优解时,可以使用贪心算法。
一般来说,贪心算法的优点是简单易懂,并且在特定情况下能够得到准确的答案。
3. C语言代码实现快速查找从起点到所有节点的距离是这个问题的关键,可以使用某种最短路算法,例如Dijkstra算法或贪心算法。
在这里,我们使用贪心算法解决最短路径问题。
以下是C语言代码示例:#include <stdio.h> #include <stdlib.h> #include <string.h>#define V 6int min_distance(int distance[], int visited[]) { int min_index, min_distance = INT_MAX;for (int i = 0; i < V; i++) { if (visited[i] == 0 && distance[i] <= min_distance){ min_distance = distance[i]; min_index = i; } }return min_index; }int dijkstra(int graph[V][V], int source, int destination) { int distance[V], visited[V], count; memset(distance, 0, sizeof(distance)); memset(visited, 0, sizeof(visited));for (int i = 0; i < V; i++){ distance[i] = INT_MAX; }distance[source] = 0;for (count = 0; count < V - 1; count++){ int u = min_distance(distance, visited);visited[u] = 1;for (int v = 0; v < V; v++){ if (!visited[v] && graph[u][v] &&distance[u] != INT_MAX && distance[u] + graph[u][v]< distance[v]) { distance[v] =distance[u] +graph[u][v]; } } }return distance[destination]; }int main() { int graph[V][V] = { { 0, 1, 0,0, 0, 0 }, { 0, 0, 9, 0, 0,0 }, { 2, 0, 0, 3, 0, 1 }, { 0, 0, 0, 0, 2, 0 }, { 4,6, 0, 2, 0, 0 }, { 0, 0, 0,0, 1, 0 } };int source = 0, destination = 5;int distance = dijkstra(graph, source,destination);printf("The shortest distance from node %dto %d is: %d\n", source, destination, distance);return 0; }4. 结尾在本文中,我们介绍了贪心算法解决最短路径问题的原理和C语言代码实现。
最短路径之Dijkstra算法详细讲解(C#)
最短路径之Dijkstra算法详细讲解1最短路径算法在日常生活中,我们如果需要常常往返A地区和B地区之间,我们最希望知道的可能是从A地区到B地区间的众多路径中,那一条路径的路途最短。
最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。
算法具体的形式包括:(1)确定起点的最短路径问题:即已知起始结点,求最短路径的问题。
(2)确定终点的最短路径问题:与确定起点的问题相反,该问题是已知终结结点,求最短路径的问题。
在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点的问题。
(3)确定起点终点的最短路径问题:即已知起点和终点,求两结点之间的最短路径。
(4)全局最短路径问题:求图中所有的最短路径。
用于解决最短路径问题的算法被称做“最短路径算法”,有时被简称作“路径算法”。
最常用的路径算法有:Dijkstra算法、A*算法、Bellman-Ford算法、Floyd-Warshall算法、Johnson算法。
本文主要研究Dijkstra算法的单源算法。
2Dijkstra算法2.1 Dijkstra算法Dijkstra算法是典型最短路算法,用于计算一个节点到其他所有节点的最短路径。
主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。
Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。
2.2 Dijkstra算法思想Dijkstra算法思想为:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径, 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U 表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。
求迷宫的最短路径 C语言代码
sqtype sq[r];
//作为队列的存储空间,记录被访问过的点
struct moved
{
int x,y;
// 坐标增量,取值-1,0,1
};
struct moved move[8]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
//
RESTORE(maze);
//恢复迷宫
return 1;
//成功,返回 1
}
}
front ++;
//出队,front 指向新的出发点
}
// 队空循环结束
return 0; //迷宫无路径,返回 0
}
void main() {
int i,j; printf("input the row,column: "); scanf("%d%d",&m,&n); for(i=0;i<m+2;i++)
int maze[m2][n2];
//迷宫数组
void PRINTPATH(sqtype sq[],int rear) {
int i=rear; do {
printf("\n(%d,%d)",sq[i].x,sq[i].y); i=sq[i].pre; }while(i!=0);
//打印输出最短路径
for(j=0;j<n+2;j++) if(i==0||i==m+1||j==0||j==n+1) maze[i][j]=-1;
c语言最短路径算法程序
c语言最短路径算法程序在计算机科学领域中,最短路径算法是一种用于找到两个节点之间最短路径的算法。
在实际应用中,最短路径算法非常重要,例如在计算机网络中,路由器需要根据最短路径算法来确定数据包的传输路径。
在这篇文章中,我们将着重探讨C语言中的最短路径算法程序。
首先,我们需要明确最短路径算法的定义。
在一个带权重的图中,每个节点代表一个地点,而边代表着这些地点之间的连接。
权重可以表示地点之间的距离、时间或者成本等。
最短路径算法的目标是找到从一个起始节点到一个目标节点的最短路径,并计算出该路径上的总权重。
在C语言中,我们可以使用多种算法来实现最短路径的计算,其中最著名的算法之一是迪杰斯特拉算法(Dijkstra's algorithm)。
该算法的基本思想是从起始节点开始,逐步找到离起始节点最近的节点,并将路径和权重记录下来。
然后,对于所有与该节点相连的节点,通过比较已知路径权重和新路径权重来更新最短路径。
重复该步骤,直到找到最短路径为止。
下面,让我们来详细讨论一下迪杰斯特拉算法的实现过程。
步骤1: 首先,我们需要定义一些数据结构来表示图的节点、边以及它们之间的关系。
通常,我们可以使用邻接矩阵或邻接表来表示图。
在C语言中,我们可以使用二维数组来表示邻接矩阵,其中矩阵的行和列分别代表节点。
步骤2: 在算法的开始阶段,我们需要对所有节点的路径权重进行初始化。
我们可以使用一个数组来存储所有节点的路径权重,用一个常量来表示无穷大的路径权重。
另外,我们还需要使用一个数组来记录已经计算完成最短路径的节点。
步骤3: 我们选择起始节点,并将其路径权重设置为0。
然后,我们将起始节点标记为已计算完成最短路径的节点。
步骤4: 接下来,我们需要遍历所有与起始节点相连的节点,并计算路径权重。
如果计算出的路径权重小于已知的路径权重,则更新该节点的路径权重。
我们可以使用循环来遍历所有与起始节点相连的节点,并使用条件语句来比较路径权重。
C语言的最短路径(迪特斯特拉)算法
起点为1 终点为3
2
初始 状态
4 1
3 从节点1开始生 长,比较2,4到1 的距离,4较短
5
从4开始成长,判断2,5 到1的距离,2较短
判断1→2→3和1→4→5→3的距离,3前 者短,则在distance中存储的是前者的值。 同时将3的flag值改为1。 从2开始成长,判断3,5到1的距 离,5短
2.创建拓扑结构
CreateArcs(SHP_RECORDS Nodes, SHP_RECORDS Edges) 1. Edges的数量与Arc的数量是相等的 2. Edges的起止点便为Arc的起止点 3. 通过Edges为Arcs分配空间并赋值,通过虚幻Node,找出Edges起 止点的ID号,也即是Arc起止点的ID。
算法的重点和难点
1. 遍历Arcs时,要取出其中的所 有不重复的点,存进head链表 中,并返回点的个数,主要通 过以下方法来实现
AddID判断点是否存在于 链表中,存在为真,不存 在为假
算法的重点和难点
2.在使用迪克斯特拉算法求最短路径的时候,可能 会有终点不在起点所在的关联点内的现象产生,即 树不断生长,却无法延伸至终点,如图所示,
在使用迪克斯特拉算法求最短路径的时候可能会有终点不在起点所在的关联点内的现象产生即树不断生长却无法延伸至终点如图所示这种情况下若起点所能关联的点全部标记为已生长点则说明找不到两点间的路径算法的重点和难点3
Arc-Node数据结构和 Dijkstra算法
第五组:王成龙,李亚飞,杜 欣威,邱陶,张军,曹恩溯、 吕佳奇
这种情况下,若起点所能关联的 点全部标记为已生长点,则 说明找不到两点间的路径
算法的重点和难点
3.链表的使用,在迪克特斯拉算法的编写中我们用到 了两次链表来分别储存headID寻找离鼠标点最近那个点时,没有采用以鼠标点为圆 心画圆的办法,而是给出一个dRadius通过将横纵坐标加减 dRadius建立一个矩形区域,以此来查找。这样就不用计算 距离了。
c语言最短路径搜寻算法
c语言最短路径搜寻算法C语言最短路径搜索算法是一种用于找到两个节点之间最短路径的算法。
它在计算机科学和图论中被广泛应用。
下面是一个详细描述C语言最短路径搜索算法的内容。
1. 定义图的表示:使用邻接矩阵或邻接表来表示图。
邻接矩阵是一个二维数组,其中行和列表示图中的节点,矩阵中的元素表示两个节点之间的边的权重。
邻接表是一种链表的数组,数组中的每个元素都是一个链表,表示与该节点相邻的节点。
2. 初始化数据结构:创建一个距离数组和一个访问数组。
距离数组用于存储从起始节点到每个节点的最短路径长度,初始时将所有元素设置为无穷大。
访问数组用于标记每个节点是否已经被访问过,初始时将所有元素设置为未访问。
3. 设置起始节点:选择一个起始节点,并将其距离数组中的值设置为0,表示从起始节点到自身的距离为0。
4. 进行最短路径搜索:使用循环来遍历所有节点,直到所有节点都被访问过为止。
在每一次循环中,选择一个未访问的节点,找到与该节点相邻的节点,并计算通过当前节点到达相邻节点的距离。
如果通过当前节点到达相邻节点的距离小于相邻节点在距离数组中的值,则更新距离数组中相邻节点的值。
同时,将当前节点标记为已访问。
5. 确定最短路径:当所有节点都被访问过后,距离数组中存储的值就是从起始节点到每个节点的最短路径长度。
可以使用一个数组来记录每个节点的前驱节点,从而确定最短路径。
6. 输出最短路径:根据前驱节点数组,从目标节点开始,沿着前驱节点一直回溯到起始节点,即可得到最短路径。
这是一个基本的C语言最短路径搜索算法的框架,具体的实现可能会有一些细微的差别,取决于使用的数据结构和算法。
在实际应用中,还可以根据具体的需求进行一些优化,例如使用优先队列来选择下一个要访问的节点,以提高搜索效率。
dijkstra算法代码c语言
dijkstra算法代码c语言Dijkstra算法代码C语言简介Dijkstra算法是一种用于寻找带权有向图中最短路径的经典算法。
它由荷兰计算机科学家Edsger Dijkstra于1956年发明。
本文将介绍Dijkstra算法的基本原理和用C语言实现的代码。
算法原理1.初始化:设定一个起始点,将起始点到其他所有点的距离初始为无穷大,将起始点到自身的距离设为0,创建一个空的集合用于存放已找到最短路径的点。
2.选取最短路径:从未找到最短路径的点中选择一个距离起始点最近的点,将其加入到已找到最短路径的点的集合中。
3.更新距离:对于新加入的点,更新它周围点到起始点的最短距离。
如果通过新加入的点到达某个点的距离比当前已知最短距离小,则更新该点的最短距离。
4.重复步骤2和步骤3,直到所有点都找到最短路径。
C语言实现下面是用C语言实现Dijkstra算法的代码:#include <>#include <>#define SIZE 10#define INFINITY 9999void dijkstra(int graph[SIZE][SIZE], int startNode) {int distance[SIZE];bool visited[SIZE];for (int i = 0; i < SIZE; i++) {distance[i] = INFINITY;visited[i] = false;}distance[startNode] = 0;for (int count = 0; count < SIZE - 1; count++) {int minDistance = INFINITY;int minIndex;for (int i = 0; i < SIZE; i++) {if (!visited[i] && distance[i] <= minDistanc e) {minDistance = distance[i];minIndex = i;}}visited[minIndex] = true;for (int i = 0; i < SIZE; i++) {if (!visited[i] && graph[minIndex][i] && dis tance[minIndex] != INFINITY &&distance[minIndex] + graph[minIndex][i] < distance[i]) {distance[i] = distance[minIndex] + graph [minIndex][i];}}}printf("最短路径为:\n");for (int i = 0; i < SIZE; i++) {printf("%d 到 %d 的距离: %d\n", startNode, i, di stance[i]);}}int main() {int graph[SIZE][SIZE] = {{0, 6, 0, 1, 0},{6, 0, 5, 2, 2},{0, 5, 0, 0, 5},{1, 2, 0, 0, 1},{0, 2, 5, 1, 0}};int startNode = 0; // 起始点的索引dijkstra(graph, startNode);return 0;}总结Dijkstra算法是解决最短路径问题的一种有效方法。
C#语言对城市最短路径搜索算法的优化
C 的 序幕是 在 20 # 0 0年 7月 在 弗 罗 里 达 州 奥 兰 多 市 举 行 的 M coot 业 开 发 人 员 大 会 上 揭 开 的 . 是 一 门从 C 和 C + 生 irsf专 它 +派 出来 的 , 简单 的 、 向对 象 的 、 型 安 全 的 语 言 。『1 集 各 种 主流 面 类 1 它
开 发语 言 的优 点 于一 身 ( 收 D lh 和 V 吸 e i p B语 言 的 简 单 易 用 , C和
代 码 只 要 略 作修 改 就 可 以 布 署 到 We b环 境 中。 M p tm 20 a Xr e 04提 供 了 复杂 而强 大 的 标 注 功 能 。它 不 仅 能通 e 过 字 段 值 或 其 组 合 、 达 式 来 标 注 对 象 , 且 您 可 以 为 标 注 创 建 表 而
独 立 值 专题 图和 范围 专 题 图 ,这 样 就 摆 脱 了对 文 字 的 依 赖 性 , 是
C + 强 大 , 及 Jv +的 以 aa的类 型 安 全 等 特 性 )所 以 C} . }问世 就 引 起
了开 发 人 员 的 广 泛关 注 C} 关 键 特 性 包括 以下 几 个 方 面 : }的
M p tm 20 a Xr e 0 4标 注 的 一个 强 势 特 征 。 a Xrm 2 0 e M p t e0 4中 , 注 除 e 标
了一 如 既 往 的 支 持 沿 线 标 注 、 分 标 注 、 绕 f 部 环 曲线 1 注 、 行 显 标 多 示 等 特 性 外 , 注 被 存 放 到 单 独 的 一 层 中 显 示 . 样 就 导 致 标 注 标 这 图层 可 以参 加 图层 排 序 ,就 不 会 出现 标 注 被 压 住 看 不 到 的 问题 。 地 理 对 象 的 创 建 与编 辑 : p t m 2 0 Ma X r e 0 4中 提供 接 1 创 建 与 编辑 e 7 : 1 地 理 对 象 , 象类 型包 括 : 、 点 、 段 曲线 、 对 点 多 多 直线 、 形 、 角 矩 矩 圆 形 . 弧段 、 义字 、 合 。 集 Ma X rm 2 0 p t e 0 4中的 一 个常 用 功 能 是 查 询 符合 条 件 的地 图 对 e
C语言求所有顶点对之间的最短路径:FLOYD算法
C语⾔求所有顶点对之间的最短路径:FLOYD算法所有顶点对之间的最短路径问题是:对于给定的有向⽹络G=(V,E),要对G中任意两个顶点v,w(v不等于w),找出v到w的最短路径。
当然我们可以n次执⾏DIJKSTRA算法,⽤FLOYD则更为直接,两种⽅法的时间复杂度都是⼀样的。
有向⽹络⽤邻接矩阵存储,以下⾯的有向⽹络为例:源程序清单:#include<stdio.h>#define n 5 //结点数⽬#define maxsize 160 //表⽰两点间不可达int path[n][n];//路径矩阵void floyd(int A[][n],int C[][n]); //A是路径长度矩阵,C是有向⽹络G的带权邻接矩阵void main(){printf(" ——所有顶点对之间的最短路径:Floyd算法——\n");printf("(160为⽆穷远,不可达)\n");int A[n][n],C[n][n]={{0,10,maxsize,30,100},{maxsize,0,50,maxsize,maxsize},{maxsize,maxsize,0,maxsize,10},{maxsize,maxsize,20,0,60},{maxsize,maxsize,maxsize,maxsize,0}};floyd(A,C);}void floyd(int A[][n],int C[][n]) //A是路径长度矩阵,C是有向⽹络G的带权邻接矩阵{int i,j,k,next;int max=160;for(i=0;i<n;i++)//设置A和path的初值{for(j=0;j<n;j++){if(C[i][j]!=max)path[i][j]=j; //j是i的后继elsepath[i][j]=0;A[i][j]=C[i][j];}}for(k=0;k<n;k++)//做n次迭代,每次均试图将顶点k扩充到当前求得的从i到j的最短路径Pij上{for(i=0;i<n;i++){for(j=0;j<n;j++){if(A[i][j]>(A[i][k]+A[k][j])){A[i][j]=A[i][k]+A[k][j]; //修改长度path[i][j]=path[i][k]; //修改路径}}}}for(i=0;i<n;i++)//输出所有顶点对i,j之间的最短路径Pij的长度及路径 {for(j=0;j<n;j++){if(i!=j){printf("%d到%d的最短距离为",i+1,j+1);printf("%d\n",A[i][j]); //输出Pij的长度next=path[i][j]; //next为起点i的后继顶点printf("输出路径:\n");if(next==0)printf("%d到%d不可达\n",i+1,j+1);else//Pij存在{printf("%d",i+1);while(next!=j){printf("——>%d",next+1); //打印后继点next=path[next][j]; //继续找下⼀个后继点}printf("——>%d\n",j+1); //打印终点}printf("****************************************************\n");}}}}运⾏结果:——所有顶点对之间的最短路径:Floyd算法——(160为⽆穷远,不可达)1到2的最短距离为10输出路径:1——>2****************************************************1到3的最短距离为50输出路径:1——>4——>3****************************************************1到4的最短距离为30输出路径:1——>4****************************************************1到5的最短距离为60输出路径:1——>4——>3——>5****************************************************2到1的最短距离为160输出路径:2到1不可达****************************************************2到3的最短距离为50输出路径:2——>3****************************************************2到4的最短距离为160输出路径:2到4不可达**************************************************** 2到5的最短距离为60输出路径:2——>3——>5**************************************************** 3到1的最短距离为160输出路径:3到1不可达**************************************************** 3到2的最短距离为160输出路径:3到2不可达**************************************************** 3到4的最短距离为160输出路径:3到4不可达**************************************************** 3到5的最短距离为10输出路径:3——>5**************************************************** 4到1的最短距离为160输出路径:4到1不可达**************************************************** 4到2的最短距离为160输出路径:4到2不可达**************************************************** 4到3的最短距离为20输出路径:4——>3**************************************************** 4到5的最短距离为30输出路径:4——>3——>5**************************************************** 5到1的最短距离为160输出路径:5到1不可达**************************************************** 5到2的最短距离为160输出路径:5到2不可达**************************************************** 5到3的最短距离为160输出路径:5到3不可达**************************************************** 5到4的最短距离为160输出路径:5到4不可达****************************************************请按任意键继续. . .。
c语言求从某个源点到其余各顶点的最短路径算法(迪杰斯特拉算法);
c语言求从某个源点到其余各顶点的最短路径算法(迪杰斯特拉算法);1. 引言1.1 概述C语言是一种广泛应用的高级编程语言,具有快速、高效和可移植等特性,在各个领域都有重要的地位。
其中,算法是C语言中不可或缺的一部分,用来解决各种实际问题。
本文将详细介绍一种重要的最短路径算法——迪杰斯特拉算法,该算法通过从某个源点到其余各顶点求解最短路径,并被广泛应用于网络路由、交通规划等领域。
1.2 文章结构本文将按照以下结构进行论述:- 引言:对文章的主题进行简要介绍和概括;- 迪杰斯特拉算法:阐述该算法的原理、步骤和流程;- 实现细节:详细描述迪杰斯特拉算法的初始化过程、松弛操作以及路径记录与输出;- 算法应用场景和实例分析:探讨无向连通图和带权有向图中最短路径问题在实际中的应用;- 结论与总结:分析迪杰斯特拉算法的优点与局限性,并与其他最短路径算法进行比较。
1.3 目的本文的目的是通过对迪杰斯特拉算法的阐述,使读者能够深入了解该算法的原理和应用,并能够在实际问题中灵活运用。
同时,通过与其他最短路径算法进行比较分析,帮助读者更好地选择适合不同场景下的最优解。
2. 迪杰斯特拉算法2.1 算法原理迪杰斯特拉算法是一种经典的最短路径算法,用于求解从一个源点到其他所有顶点的最短路径。
该算法采用了贪心策略和动态规划的思想。
其基本原理是初始化一个距离数组,将源点到自身的距离设为0,其他顶点到源点的距离全部设为无穷大。
然后以逐步扩展的方式,不断更新各个顶点之间的最短路径信息,直到求得所有顶点相对于源点的最短路径。
2.2 步骤和流程具体而言,迪杰斯特拉算法按照以下步骤执行:(1)初始化:建立图的邻接表,并创建一个大小等于顶点数的距离数组dist[],用来存储源点到各个顶点之间的最短距离。
同时创建一个大小等于顶点数的前驱数组predecessor[],用来记录最短路径上每个顶点的前驱节点。
(2)设置源点:将源节点标记为已访问,并将其与源节点之间的距离设置为0。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#define INFINITY 32767 //INF 表示无穷大
#define MAX_VERTEX_NUM 10
typedef struct
{
int edge; //边的权值
}AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //两点之间路径长度
typedef struct //景点信息
{
char name[30];
int num;
}infotype;
typedef struct
{
infotype vexs[MAX_VERTEX_NUM]; //顶点向量
AdjMatrix arcs; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和弧数
}MGraph;
MGraph b;
//函数声明
MGraph InitGraph();
void Floyd(MGraph *G);
void Menu();
void cmd();
MGraph InitGraph()//初始化顶点和权值
{
MGraph G;
int i,j;
G.vexnum=6;
G.arcnum=6;
for(i=0;i<G.vexnum;i++)
G.vexs[i].num=i;
strcpy(G.vexs[0].name,"十堰");
strcpy(G.vexs[1].name,"襄樊");
strcpy(G.vexs[2].name,"随州");
strcpy(G.vexs[3].name,"武汉");
strcpy(G.vexs[4].name,"黄石");
strcpy(G.vexs[5].name,"荆州");
strcpy(G.vexs[6].name,"宜昌");
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
{ G.arcs[i][j].edge=INFINITY;
if(i==j) G.arcs[i][j].edge=0;}
G.arcs[0][1].edge=G.arcs[1][0].edge=145;
G.arcs[1][2].edge=G.arcs[2][1].edge=124;
G.arcs[1][5].edge=G.arcs[5][1].edge=188;
G.arcs[1][6].edge=G.arcs[6][1].edge=169;
G.arcs[2][3].edge=G.arcs[3][2].edge=149;
G.arcs[2][5].edge=G.arcs[5][2].edge=187;
G.arcs[3][4].edge=G.arcs[4][3].edge=83;
G.arcs[4][5].edge=G.arcs[5][4].edge=269;
G.arcs[5][6].edge=G.arcs[6][5].edge=178;
return G;
}
/*Floyd算法求最短路径*/
void Floyd(MGraph *G)
{
int v,u,i,w,k,j,flag=1,p[11][11][11],D[11][11];
for(v=0;v<G->vexnum;++v)
for(w=0;w<G->vexnum;++w)
{
D[v][w]=G->arcs[v][w].edge;//从v到w之间的路径长度赋值给D[v][w]
for(u=0;u<G->vexnum;++u)
p[v][w][u]=0;//u不是v到w之间最短路径上的顶点
if(D[v][w]<INFINITY)//从v到w之间有直接路径
{
p[v][w][v]=1;p[v][w][w]=1;
}
}
for(u=0;u<G->vexnum;++u)
for(v=0;v<G->vexnum;++v)
for(w=0;w<G->vexnum;++w)
if(D[v][u]+D[u][w]<D[v][w])//从v到w经过u的一条更短的路径
{
D[v][w]=D[v][u]+D[u][w];//最短路径的累加
for(i=0;i<G->vexnum;++i)
p[v][w][i]=p[v][u][i] || p[u][w][i];//分半开始找途径i,v和u 之间或w和u之间的路径长度
}
while(flag)
{
printf("请输入出发点和目的地的编号(注意:输入编号时用空格号分割):");
scanf("%d%d",&k,&j);
if(k<0 || k>G->vexnum || j<0 || j>G->vexnum)
{
printf("景点编号不存在!请重新输入起点和终点的编号:");
scanf("%d %d",&k,&j);
}
if(k>=0 && k<G->vexnum && j>=0 && j<G->vexnum )
flag=0;
}
printf("\n");
printf("%s",G->vexs[k].name);
for(u=0;u<G->vexnum;++u)
if(p[k][j][u] && k!=u && j!=u && D[k][j]!=INFINITY)
printf("-->%s",G->vexs[u].name);//输出途径的景点
printf("-->%s",G->vexs[j].name);
printf(" 最短路径为: %dm\n",D[k][j]);
if(D[k][j]==INFINITY) printf("\n无法到达!\n");
}
void Menu()//菜单界面
{
printf("\n\n\n");
printf("\t\t *--------------------------------------*\t\n");
printf("\t\t *-----欢迎使用湖北省地图路径查询程序---*\t\n");
printf("\t\t ****************************************\t\n");
printf("\t\t *--------------------------------------*\t\n");
printf("\t\t * 1.选择出发点和目的地*\t\n");
printf("\t\t * 2.退出系统*\t\n");
printf("\t\t *--------------------------------------*\t\n");
printf("\t\t ****************************************\t\n");
printf("请您选择操作:");
}
/*菜单选择*/
void cmd()
{
int i;
b=InitGraph();
Menu();
scanf("%d",&i);
while(i!=5)
{
switch(i)
{
case 1:
system("cls"); //清除屏幕
Floyd(&b);
Menu();
break;
case 2:
getchar();
exit(1);
break;
default:
system("cls");
cmd();
break;
}
scanf("%d",&i);
}
}
void main()
{
cmd();
}。