鱼C论坛

 找回密码
 立即注册
查看: 387|回复: 1

[已解决]迪杰斯特拉算法用邻接表存储赋权图

[复制链接]
发表于 2023-6-13 20:48:31 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
迪杰斯特拉算法用邻接表存储赋权图怎么实现;用c语言,谢谢嘞
最佳答案
2023-6-13 20:56:40
Dijkstra算法是一种常用的最短路径算法,下面我会用C语言展示一个利用邻接表来存储赋权图的版本。首先,我们需要定义邻接表的节点结构和邻接表本身的结构:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define INFINITY 999999
  4. #define MAX 10

  5. // 邻接表的节点结构
  6. typedef struct node {
  7.     int vertex;     // 顶点编号
  8.     int weight;     // 边的权值
  9.     struct node* next;  // 指向下一个节点的指针
  10. } node;

  11. // 邻接表的结构
  12. typedef struct Graph {
  13.     int numVertices;   // 顶点数量
  14.     struct node** adjLists; // 邻接表数组
  15.     int* distance;   // 保存每个顶点到源顶点的最短距离
  16. } Graph;

  17. // 创建节点
  18. node* createNode(int v, int weight) {
  19.     node* newNode = malloc(sizeof(node));
  20.     newNode->vertex = v;
  21.     newNode->weight = weight;
  22.     newNode->next = NULL;
  23.     return newNode;
  24. }

  25. // 创建图
  26. Graph* createGraph(int vertices) {
  27.     Graph* graph = malloc(sizeof(Graph));
  28.     graph->numVertices = vertices;
  29.     graph->adjLists = malloc(vertices * sizeof(node*));
  30.     graph->distance = malloc(vertices * sizeof(int));
  31.    
  32.     int i;
  33.     for (i = 0; i < vertices; i++) {
  34.         graph->adjLists[i] = NULL;
  35.         graph->distance[i] = INFINITY;
  36.     }
  37.     return graph;
  38. }

  39. // 添加边
  40. void addEdge(Graph* graph, int src, int dest, int weight) {
  41.     // 从src到dest的边
  42.     node* newNode = createNode(dest, weight);
  43.     newNode->next = graph->adjLists[src];
  44.     graph->adjLists[src] = newNode;

  45.     // 在无向图中添加从dest到src的边
  46.     newNode = createNode(src, weight);
  47.     newNode->next = graph->adjLists[dest];
  48.     graph->adjLists[dest] = newNode;
  49. }
复制代码


然后,我们需要实现Dijkstra算法本身:

  1. // 找到距离源顶点最近的顶点
  2. int findMinVertex(Graph* graph, int* visited) {
  3.     int minVertex = -1;
  4.     for (int i = 0; i < graph->numVertices; i++) {
  5.         if (!visited[i] && (minVertex == -1 || graph->distance[i] < graph->distance[minVertex])) {
  6.             minVertex = i;
  7.         }
  8.     }
  9.     return minVertex;
  10. }

  11. // 执行Dijkstra算法
  12. void dijkstra(Graph* graph, int startVertex) {
  13.     int visited[MAX] = {0};
  14.     graph->distance[startVertex] = 0;

  15.     for (int i = 0; i < graph->numVertices - 1; i++) {
  16.         int minVertex = findMinVertex(graph, visited);
  17.         visited[minVertex] = 1;

  18.         node* adjList = graph->adjLists[minVertex];
  19.         while (adjList != NULL) {
  20.             int adjVertex = adjList->vertex;
  21.             if (!visited[adjVertex] && graph->distance[minVertex] != INFINITY
  22.                 && graph->distance[adjVertex] > graph->distance[minVertex] + adjList->weight) {
  23.                 graph->distance[adjVertex] = graph->distance[minVertex] + adjList->weight;
  24.             }
  25.             adjList = adjList->next;
  26.         }
  27.     }
  28. }

  29. // 打印结果
  30. void printGraph(Graph* graph) {
  31.     for (int i = 0; i < graph->numVertices; i++)
  32.         printf("Vertex %d -> distance = %d\n", i, graph->distance[i]);
  33. }
复制代码


最后,我们可以在main函数中测试这个算法:

  1. int main() {
  2.     Graph* graph = createGraph(6);
  3.     addEdge(graph, 0, 1, 4);
  4.     addEdge(graph, 0, 2, 2);
  5.     addEdge(graph, 1, 2, 1);
  6.     addEdge(graph, 1, 3, 5);
  7.     addEdge(graph, 2, 3, 8);
  8.     addEdge(graph, 2, 4, 10);
  9.     addEdge(graph, 3, 5, 6);
  10.     addEdge(graph, 4, 5, 2);
  11.    
  12.     dijkstra(graph, 0);
  13.     printGraph(graph);
  14.    
  15.     return 0;
  16. }
复制代码


以上就是一个基于邻接表实现的Dijkstra算法的例子。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-6-13 20:56:40 | 显示全部楼层    本楼为最佳答案   
Dijkstra算法是一种常用的最短路径算法,下面我会用C语言展示一个利用邻接表来存储赋权图的版本。首先,我们需要定义邻接表的节点结构和邻接表本身的结构:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define INFINITY 999999
  4. #define MAX 10

  5. // 邻接表的节点结构
  6. typedef struct node {
  7.     int vertex;     // 顶点编号
  8.     int weight;     // 边的权值
  9.     struct node* next;  // 指向下一个节点的指针
  10. } node;

  11. // 邻接表的结构
  12. typedef struct Graph {
  13.     int numVertices;   // 顶点数量
  14.     struct node** adjLists; // 邻接表数组
  15.     int* distance;   // 保存每个顶点到源顶点的最短距离
  16. } Graph;

  17. // 创建节点
  18. node* createNode(int v, int weight) {
  19.     node* newNode = malloc(sizeof(node));
  20.     newNode->vertex = v;
  21.     newNode->weight = weight;
  22.     newNode->next = NULL;
  23.     return newNode;
  24. }

  25. // 创建图
  26. Graph* createGraph(int vertices) {
  27.     Graph* graph = malloc(sizeof(Graph));
  28.     graph->numVertices = vertices;
  29.     graph->adjLists = malloc(vertices * sizeof(node*));
  30.     graph->distance = malloc(vertices * sizeof(int));
  31.    
  32.     int i;
  33.     for (i = 0; i < vertices; i++) {
  34.         graph->adjLists[i] = NULL;
  35.         graph->distance[i] = INFINITY;
  36.     }
  37.     return graph;
  38. }

  39. // 添加边
  40. void addEdge(Graph* graph, int src, int dest, int weight) {
  41.     // 从src到dest的边
  42.     node* newNode = createNode(dest, weight);
  43.     newNode->next = graph->adjLists[src];
  44.     graph->adjLists[src] = newNode;

  45.     // 在无向图中添加从dest到src的边
  46.     newNode = createNode(src, weight);
  47.     newNode->next = graph->adjLists[dest];
  48.     graph->adjLists[dest] = newNode;
  49. }
复制代码


然后,我们需要实现Dijkstra算法本身:

  1. // 找到距离源顶点最近的顶点
  2. int findMinVertex(Graph* graph, int* visited) {
  3.     int minVertex = -1;
  4.     for (int i = 0; i < graph->numVertices; i++) {
  5.         if (!visited[i] && (minVertex == -1 || graph->distance[i] < graph->distance[minVertex])) {
  6.             minVertex = i;
  7.         }
  8.     }
  9.     return minVertex;
  10. }

  11. // 执行Dijkstra算法
  12. void dijkstra(Graph* graph, int startVertex) {
  13.     int visited[MAX] = {0};
  14.     graph->distance[startVertex] = 0;

  15.     for (int i = 0; i < graph->numVertices - 1; i++) {
  16.         int minVertex = findMinVertex(graph, visited);
  17.         visited[minVertex] = 1;

  18.         node* adjList = graph->adjLists[minVertex];
  19.         while (adjList != NULL) {
  20.             int adjVertex = adjList->vertex;
  21.             if (!visited[adjVertex] && graph->distance[minVertex] != INFINITY
  22.                 && graph->distance[adjVertex] > graph->distance[minVertex] + adjList->weight) {
  23.                 graph->distance[adjVertex] = graph->distance[minVertex] + adjList->weight;
  24.             }
  25.             adjList = adjList->next;
  26.         }
  27.     }
  28. }

  29. // 打印结果
  30. void printGraph(Graph* graph) {
  31.     for (int i = 0; i < graph->numVertices; i++)
  32.         printf("Vertex %d -> distance = %d\n", i, graph->distance[i]);
  33. }
复制代码


最后,我们可以在main函数中测试这个算法:

  1. int main() {
  2.     Graph* graph = createGraph(6);
  3.     addEdge(graph, 0, 1, 4);
  4.     addEdge(graph, 0, 2, 2);
  5.     addEdge(graph, 1, 2, 1);
  6.     addEdge(graph, 1, 3, 5);
  7.     addEdge(graph, 2, 3, 8);
  8.     addEdge(graph, 2, 4, 10);
  9.     addEdge(graph, 3, 5, 6);
  10.     addEdge(graph, 4, 5, 2);
  11.    
  12.     dijkstra(graph, 0);
  13.     printGraph(graph);
  14.    
  15.     return 0;
  16. }
复制代码


以上就是一个基于邻接表实现的Dijkstra算法的例子。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 20:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表