Minimum Spanning Trees - Prim’s algorithm & Single-Source Shortest Paths - Dijkstra’s algorithm

本文深入探讨了最小生成树算法(Kruskal, Prim)与单源最小路径算法(Bellman-Ford, Dijkstra)的核心原理、实现方式及应用案例,通过对比分析帮助读者理解算法之间的区别与联系。

前者用于最小生成树;后者用于单源最小路径搜索。


两者均通过维护待处理节点队列中的当前“最小”信息完成新节点的并入:

前者维护的是到部分树的最短距离;后者维护的是到源节点的最短距离。



前者用于最小生成树;后者用于单源最小路径搜索。


最小生成树算法:Kruskal,Prim

单源最小路径算法:Bellman-Ford,Dijkstra


#include <stdio.h> #include <stdlib.h> #include <limits.h> #define MAX_VERTICES 100 // 图的邻接矩阵表示 typedef struct { int vertices[MAX_VERTICES][MAX_VERTICES]; int num_vertices; } Graph; // 初始化图 void init_graph(Graph *g, int num_vertices) { g->num_vertices = num_vertices; for (int i = 0; i < num_vertices; i++) { for (int j = 0; j < num_vertices; j++) { if (i == j) { g->vertices[i][j] = 0; } else { g->vertices[i][j] = INT_MAX; } } } } // 添加边 void add_edge(Graph *g, int src, int dest, int weight) { g->vertices[src][dest] = weight; g->vertices[dest][src] = weight; // 无向图 } // 深度优先搜索 void DFS(Graph *g, int vertex, int visited[]) { visited[vertex] = 1; printf("%d ", vertex); for (int i = 0; i < g->num_vertices; i++) { if (g->vertices[vertex][i] != INT_MAX && !visited[i]) { DFS(g, i, visited); } } } // 广度优先搜索 void BFS(Graph *g, int start) { int visited[MAX_VERTICES] = {0}; int queue[MAX_VERTICES]; int front = 0, rear = 0; visited[start] = 1; queue[rear++] = start; while (front < rear) { int vertex = queue[front++]; printf("%d ", vertex); for (int i = 0; i < g->num_vertices; i++) { if (g->vertices[vertex][i] != INT_MAX && !visited[i]) { visited[i] = 1; queue[rear++] = i; } } } } // Dijkstra 最短路径算法 void dijkstra(Graph *g, int start) { int dist[MAX_VERTICES]; int sptSet[MAX_VERTICES] = {0}; for (int i = 0; i < g->num_vertices; i++) { dist[i] = INT_MAX; } dist[start] = 0; for (int count = 0; count < g->num_vertices - 1; count++) { int min_dist = INT_MAX, min_index; for (int v = 0; v < g->num_vertices; v++) { if (!sptSet[v] && dist[v] <= min_dist) { min_dist = dist[v]; min_index = v; } } sptSet[min_index] = 1; for (int v = 0; v < g->num_vertices; v++) { if (!sptSet[v] && g->vertices[min_index][v] != INT_MAX && dist[min_index] != INT_MAX && dist[min_index] + g->vertices[min_index][v] < dist[v]) { dist[v] = dist[min_index] + g->vertices[min_index][v]; } } } printf("\nDijkstra's shortest paths from vertex %d:\n", start); for (int i = 0; i < g->num_vertices; i++) { printf("To vertex %d: %d\n", i, dist[i]); } } // Prim 最小生成树算法 void prim(Graph *g) { int parent[MAX_VERTICES]; int key[MAX_VERTICES]; int mstSet[MAX_VERTICES] = {0}; for (int i = 0; i < g->num_vertices; i++) { key[i] = INT_MAX; } key[0] = 0; parent[0] = -1; for (int count = 0; count < g->num_vertices - 1; count++) { int min_key = INT_MAX, min_index; for (int v = 0; v < g->num_vertices; v++) { if (!mstSet[v] && key[v] <= min_key) { min_key = key[v]; min_index = v; } } mstSet[min_index] = 1; for (int v = 0; v < g->num_vertices; v++) { if (!mstSet[v] && g->vertices[min_index][v] != INT_MAX && g->vertices[min_index][v] < key[v]) { parent[v] = min_index; key[v] = g->vertices[min_index][v]; } } } printf("\nPrim's Minimum Spanning Tree:\n"); for (int i = 1; i < g->num_vertices; i++) { printf("%d - %d \t%d \n", parent[i], i, g->vertices[i][parent[i]]); } } int main() { Graph g; int num_vertices = 6; init_graph(&g, num_vertices); add_edge(&g, 0, 1, 6); add_edge(&g, 0, 2, 1); add_edge(&g, 0, 3, 5); add_edge(&g, 1, 2, 5); add_edge(&g, 1, 4, 3); add_edge(&g, 2, 3, 5); add_edge(&g, 2, 4, 6); add_edge(&g, 2, 5, 4); add_edge(&g, 3, 5, 2); add_edge(&g, 4, 5, 6); printf("DFS traversal: "); int visited[MAX_VERTICES] = {0}; DFS(&g, 0, visited); printf("\n"); printf("BFS traversal: "); BFS(&g, 0); printf("\n"); dijkstra(&g, 0); prim(&g); return 0; } 此代码带全无向图是什么样子的和操作原理的具体示意图
最新发布
12-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值