数据结构kruskal,prime,Floyd,Dijkstra算法的区别(精简版)

在学完这四种算法后,感觉有点乱,现在查阅资料和借鉴_(*^▽^*)_后理清了。

克鲁斯卡尔算法:
目的:找到全图最小权值和路径

方法:以边的角度看待问题,在一个图里,找到最小的边长,并且不允许出现有回路的情况。最终形成的图就是把各个节点连接起来的最小值。

普里姆算法:

目的:找到全图最小权值和路径

方法:以某个点开始,以点的角度看待问题,在一个图里,假设从A点开始,找到离A点最近的B点;找到离B点最近的C点,直到把一个图的所有点串起来。

上面这两个因为目的相同可以归为一类。

下面这两个因为只是到所有点到最短路径的源点考虑数量的区别可以归为一类。

迪杰斯特拉算法:

目的:找到单源点到图中所有点的最短路径(就是在这条路上,A点到B点,A点到C点,A点到D点都是A点到对应的点的最短距离。

方法:以单源点A点开始,并选定一个数组,先确定未遍历前的初始距离,把距离最短的邻接结点B点选定为中间结点,并标记访问过,开始往下遍历,挨个访问B点的邻接结点C、D....点。计算出A点到B点+B点到C、D...点的距离,作为新距离,对比新距离和旧距离(A到C、D...点的直接距离),如果新距离大,则把新距离替换掉旧距离,否则不变。一轮访问结束后,从未标记的结点中选定距离最短的,把它作为中间结点,继续往下访问。若都标记过,则算法结束。

弗洛伊德算法:

目的:找到多源点到图中所有点的最短路径(就是这条路上任意两点之间都是最短的)

方法:不断找点进行中转,比较中转前后最小距离。弗洛伊德算法定义了两个二维矩阵:
D矩阵存放最小权(最短路径),P矩阵存放最短前驱(中转点)
1、矩阵D记录顶点间的最小路径
例如D[1][2]= 3,说明顶点1 到 2 的最短路径为3;
2、矩阵P记录顶点间最小路径中的中转点
例如P[1][2]= 0 说明,1 到 2的最短路径轨迹为:1 -> 0 -> 2。
它通过3重循环,medium为中转点,begin为起点,end为终点,循环比较D[begin][end] 和 D[begin][medium] + D[medium][end] 之间的最小值,如果(D[begin][medium] + D[medium][end] )为更小值,则把(D[begin][medium] + D[medium][end] )覆盖保存在(D[begin][end])中。
 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
对于Prim、KruskalFloydDijkstra算法的C语言代码,我可以为您提供一些示例。请注意,以下代码仅供参考,实际应用时可能需要根据具体情况进行调整。 1. Prim算法(最小生成树): ```c #include <stdio.h> #include <stdbool.h> #define INF 9999 #define V 5 int minKey(int key[], bool mstSet[]) { int min = INF, min_index; for (int v = 0; v < V; v++) { if (mstSet[v] == false && key[v] < min) { min = key[v]; min_index = v; } } return min_index; } void printMST(int parent[], int graph[V][V]) { printf("Edge \tWeight\n"); for (int i = 1; i < V; i++) { printf("%d - %d \t%d \n", parent[i], i, graph[i][parent[i]]); } } void primMST(int graph[V][V]) { int parent[V]; int key[V]; bool mstSet[V]; for (int i = 0; i < V; i++) { key[i] = INF; mstSet[i] = false; } key[0] = 0; parent[0] = -1; for (int count = 0; count < V - 1; count++) { int u = minKey(key, mstSet); mstSet[u] = true; for (int v = 0; v < V; v++) { if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v]) { parent[v] = u; key[v] = graph[u][v]; } } } printMST(parent, graph); } int main() { int graph[V][V] = { {0, 2, 0, 6, 0}, {2, 0, 3, 8, 5}, {0, 3, 0, 0, 7}, {6, 8, 0, 0, 9}, {0, 5, 7, 9, 0} }; primMST(graph); return 0; } ``` 2. Kruskal算法(最小生成树): ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define V 5 #define MAX_EDGES 10 struct Edge { int src, dest, weight; }; struct Graph { int V, E; struct Edge edges[MAX_EDGES]; }; struct Graph* createGraph(int V, int E) { struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph)); graph->V = V; graph->E = E; return graph; } int find(int parent[], int i) { if (parent[i] == -1) return i; return find(parent, parent[i]); } void Union(int parent[], int x, int y) { int xset = find(parent, x); int yset = find(parent, y); parent[xset] = yset; } int compare(const void* a, const void* b) { struct Edge* a1 = (struct Edge*)a; struct Edge* b1 = (struct Edge*)b; return a1->weight - b1->weight; } void kruskalMST(struct Graph* graph) { int parent[V]; int i, j; int edgeCount = 0; qsort(graph->edges, graph->E, sizeof(graph->edges[0]), compare); for (i = 0; i < V; i++) parent[i] = -1; i = 0; while (edgeCount < V - 1 && i < graph->E) { struct Edge nextEdge = graph->edges[i++]; int x = find(parent, nextEdge.src); int y = find(parent, nextEdge.dest); if (x != y) { printf("%d - %d\t%d\n", nextEdge.src, nextEdge.dest, nextEdge.weight); Union(parent, x, y); edgeCount++; } } } int main() { int V = 5; int E = 7; struct Graph* graph = createGraph(V, E); graph->edges[0].src = 0; graph->edges[0].dest = 1; graph->edges[0].weight = 2; graph->edges[1].src = 0; graph->edges[1].dest = 3; graph->edges[1].weight = 6; // 以此类推,添加其他边的信息... kruskalMST(graph); return 0; } ``` 3. Floyd算法(最短路径): ```c #include <stdio.h> #define V 4 #define INF 99999 void printSolution(int dist[][V]); void floydWarshall(int graph[][V]) { int dist[V][V], i, j, k; for (i = 0; i < V; i++) { for (j = 0; j < V; j++) { dist[i][j] = graph[i][j]; } } for (k = 0; k < V; k++) { for (i = 0; i < V; i++) { for (j = 0; j < V; j++) { if (dist[i][k] + dist[k][j] < dist[i][j]) { dist[i][j] = dist[i][k] + dist[k][j]; } } } } printSolution(dist); } void printSolution(int dist[][V]) { printf("The following matrix shows the shortest distances between every pair of vertices:\n"); for (int i = 0; i < V; i++) { for (int j = 0; j < V; j++) { if (dist[i][j] == INF) { printf("%7s", "INF"); } else { printf("%7d", dist[i][j]); } } printf("\n"); } } int main() { int graph[V][V] = { {0, 5, INF, 10}, {INF, 0, 3, INF}, {INF, INF, 0, 1}, {INF, INF, INF, 0} }; floydWarshall(graph); return 0; } ``` 4. Dijkstra算法(最短路径): ```c #include <stdio.h> #include <stdbool.h> #define V 6 #define INF 9999 int minDistance(int dist[], bool sptSet[]) { int min = INF, min_index; for (int v = 0; v < V; v++) { if (sptSet[v] == false && dist[v] <= min) { min = dist[v]; min_index = v; } } return min_index; } void printSolution(int dist[]) { printf("Vertex \t\t Distance from Source\n"); for (int i = 0; i < V; i++) { printf("%d \t\t %d\n", i, dist[i]); } } void dijkstra(int graph[V][V], int src) { int dist[V]; bool sptSet[V]; for (int i = 0; i < V; i++) { dist[i] = INF; sptSet[i] = false; } dist[src] = 0; for (int count = 0; count < V - 1; count++) { int u = minDistance(dist, sptSet); sptSet[u] = true; for (int v = 0; v < V; v++) { if (!sptSet[v] && graph[u][v] && dist[u] != INF && dist[u] + graph[u][v] < dist[v]) { dist[v] = dist[u] + graph[u][v]; } } } printSolution(dist); } int main() { int graph[V][V] = { {0, 4, 0, 0, 0, 0}, {4, 0, 8, 0, 0, 0}, {0, 8, 0, 7, 0, 4}, {0, 0, 7, 0, 9, 14}, {0, 0, 0, 9, 0, 10}, {0, 0, 4, 14, 10, 0} }; dijkstra(graph, 0); return 0; } ``` 以上是Prim、KruskalFloydDijkstra算法的一些示例C语言代码。希望对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq030928

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值