鱼C论坛

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

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

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

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

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

x
迪杰斯特拉算法用邻接表存储赋权图怎么实现;用c语言,谢谢嘞
最佳答案
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算法的例子。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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算法的例子。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 10:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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