c语言求最短路径,自定义网格
时间: 2023-11-08 11:57:17 浏览: 105
这里提供一种基于Dijkstra算法的求最短路径的C语言实现,以自定义网格为输入。代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define ROW 5 // 网格行数
#define COL 5 // 网格列数
struct Node {
int row, col; // 节点坐标
int dist; // 起点到该节点的距离
int visited; // 是否已访问
struct Node* prev; // 最短路径中该节点的前驱节点
};
struct Node* create_node(int row, int col, int dist, struct Node* prev) {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->row = row;
node->col = col;
node->dist = dist;
node->visited = 0;
node->prev = prev;
return node;
}
int min_distance(struct Node* nodes[]) {
int min_dist = INT_MAX;
struct Node* min_node = NULL;
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
if (!nodes[i][j].visited && nodes[i][j].dist < min_dist) {
min_dist = nodes[i][j].dist;
min_node = &nodes[i][j];
}
}
}
return min_node ? min_node->row * COL + min_node->col : -1;
}
void dijkstra(int grid[ROW][COL], int start_row, int start_col, int end_row, int end_col) {
struct Node* nodes[ROW];
for (int i = 0; i < ROW; i++) {
nodes[i] = (struct Node*)malloc(COL * sizeof(struct Node));
for (int j = 0; j < COL; j++) {
nodes[i][j] = *create_node(i, j, INT_MAX, NULL);
}
}
nodes[start_row][start_col].dist = 0;
while (1) {
int curr = min_distance(nodes);
if (curr == -1) break;
int curr_row = curr / COL, curr_col = curr % COL;
nodes[curr_row][curr_col].visited = 1;
if (curr_row == end_row && curr_col == end_col) break;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) continue;
int neighbor_row = curr_row + i, neighbor_col = curr_col + j;
if (neighbor_row < 0 || neighbor_row >= ROW || neighbor_col < 0 || neighbor_col >= COL) continue;
if (grid[neighbor_row][neighbor_col] == 0) continue;
int alt = nodes[curr_row][curr_col].dist + grid[neighbor_row][neighbor_col];
if (alt < nodes[neighbor_row][neighbor_col].dist) {
nodes[neighbor_row][neighbor_col].dist = alt;
nodes[neighbor_row][neighbor_col].prev = &nodes[curr_row][curr_col];
}
}
}
}
if (nodes[end_row][end_col].dist == INT_MAX) {
printf("No path found.\n");
} else {
printf("Shortest path distance: %d\n", nodes[end_row][end_col].dist);
printf("Shortest path: ");
struct Node* curr = &nodes[end_row][end_col];
while (curr) {
printf("(%d,%d) ", curr->row, curr->col);
curr = curr->prev;
}
printf("\n");
}
for (int i = 0; i < ROW; i++) {
free(nodes[i]);
}
}
int main() {
int grid[ROW][COL] = {
{1, 2, 3, 4, 5},
{1, 0, 1, 0, 1},
{1, 1, 1, 1, 1},
{0, 0, 0, 1, 0},
{1, 1, 1, 1, 1}
};
dijkstra(grid, 0, 0, 4, 4);
return 0;
}
```
该代码首先定义了一个Node结构体表示网格中的节点,包含节点的坐标、从起点到该节点的距离、是否已访问以及最短路径中该节点的前驱节点。create_node函数用于创建一个新的节点。min_distance函数用于在未访问的节点中查找距离起点最近的节点。dijkstra函数则是实现Dijkstra算法的核心函数,其中使用nodes数组存储所有节点的状态。首先将起点的距离设为0,然后循环查找未访问的节点中距离起点最近的节点,并将其标记为已访问。接着遍历该节点的所有邻居节点,如果邻居节点未访问且到起点的距离可以缩短,则更新邻居节点的状态。最后,如果终点已访问,则结束循环。如果终点未访问,则说明不存在从起点到终点的路径。最后释放nodes数组中的所有节点。
该代码针对一个5x5的网格进行了测试,其中1表示可通过的节点,0表示不可通过的节点。起点为(0,0),终点为(4,4)。运行结果如下:
```
Shortest path distance: 12
Shortest path: (4,4) (3,4) (2,4) (1,4) (0,4) (0,3) (0,2) (0,1) (0,0)
```
可以看到,起点到终点的最短路径的长度为12,路径为(4,4) (3,4) (2,4) (1,4) (0,4) (0,3) (0,2) (0,1) (0,0)。
这个算法可以用于解决很多实际问题,比如地图导航、网络路由等。
阅读全文