|
发表于 2023-6-13 20:56:40
|
显示全部楼层
本楼为最佳答案
 Dijkstra算法是一种常用的最短路径算法,下面我会用C语言展示一个利用邻接表来存储赋权图的版本。首先,我们需要定义邻接表的节点结构和邻接表本身的结构:
- #include <stdio.h>
- #include <stdlib.h>
- #define INFINITY 999999
- #define MAX 10
- // 邻接表的节点结构
- typedef struct node {
- int vertex; // 顶点编号
- int weight; // 边的权值
- struct node* next; // 指向下一个节点的指针
- } node;
- // 邻接表的结构
- typedef struct Graph {
- int numVertices; // 顶点数量
- struct node** adjLists; // 邻接表数组
- int* distance; // 保存每个顶点到源顶点的最短距离
- } Graph;
- // 创建节点
- node* createNode(int v, int weight) {
- node* newNode = malloc(sizeof(node));
- newNode->vertex = v;
- newNode->weight = weight;
- newNode->next = NULL;
- return newNode;
- }
- // 创建图
- Graph* createGraph(int vertices) {
- Graph* graph = malloc(sizeof(Graph));
- graph->numVertices = vertices;
- graph->adjLists = malloc(vertices * sizeof(node*));
- graph->distance = malloc(vertices * sizeof(int));
-
- int i;
- for (i = 0; i < vertices; i++) {
- graph->adjLists[i] = NULL;
- graph->distance[i] = INFINITY;
- }
- return graph;
- }
- // 添加边
- void addEdge(Graph* graph, int src, int dest, int weight) {
- // 从src到dest的边
- node* newNode = createNode(dest, weight);
- newNode->next = graph->adjLists[src];
- graph->adjLists[src] = newNode;
- // 在无向图中添加从dest到src的边
- newNode = createNode(src, weight);
- newNode->next = graph->adjLists[dest];
- graph->adjLists[dest] = newNode;
- }
复制代码
然后,我们需要实现Dijkstra算法本身:
- // 找到距离源顶点最近的顶点
- int findMinVertex(Graph* graph, int* visited) {
- int minVertex = -1;
- for (int i = 0; i < graph->numVertices; i++) {
- if (!visited[i] && (minVertex == -1 || graph->distance[i] < graph->distance[minVertex])) {
- minVertex = i;
- }
- }
- return minVertex;
- }
- // 执行Dijkstra算法
- void dijkstra(Graph* graph, int startVertex) {
- int visited[MAX] = {0};
- graph->distance[startVertex] = 0;
- for (int i = 0; i < graph->numVertices - 1; i++) {
- int minVertex = findMinVertex(graph, visited);
- visited[minVertex] = 1;
- node* adjList = graph->adjLists[minVertex];
- while (adjList != NULL) {
- int adjVertex = adjList->vertex;
- if (!visited[adjVertex] && graph->distance[minVertex] != INFINITY
- && graph->distance[adjVertex] > graph->distance[minVertex] + adjList->weight) {
- graph->distance[adjVertex] = graph->distance[minVertex] + adjList->weight;
- }
- adjList = adjList->next;
- }
- }
- }
- // 打印结果
- void printGraph(Graph* graph) {
- for (int i = 0; i < graph->numVertices; i++)
- printf("Vertex %d -> distance = %d\n", i, graph->distance[i]);
- }
复制代码
最后,我们可以在main函数中测试这个算法:
- int main() {
- Graph* graph = createGraph(6);
- addEdge(graph, 0, 1, 4);
- addEdge(graph, 0, 2, 2);
- addEdge(graph, 1, 2, 1);
- addEdge(graph, 1, 3, 5);
- addEdge(graph, 2, 3, 8);
- addEdge(graph, 2, 4, 10);
- addEdge(graph, 3, 5, 6);
- addEdge(graph, 4, 5, 2);
-
- dijkstra(graph, 0);
- printGraph(graph);
-
- return 0;
- }
复制代码
以上就是一个基于邻接表实现的Dijkstra算法的例子。 |
|