数据结构与算法学习之路:Prim算法和Kruskal算法

来源:互联网 发布:双色球关注倾向数据 编辑:程序博客网 时间:2024/06/01 10:23

一、Prim算法和Kruskal算法是什么?

Prim算法:首先把图中所有顶点看作未被访问的点的点集——>随意挑选其中一个点,并把该点放入已被访问过的点的点集——>不断的寻找与被访问点集中的点距离最短的,并且未被访问过的点,加入被访问点集——>当所有点都进入被访问点集,则获得图的最小生成树。


Prim算法查找过程:


Kruskal算法:获得图中所有具有权值的边,从中挑选权值最小的边,若边会与已挑选边形成回路,则该边;不形成回路,则加入最小生成树。


Kruskal算法查找过程:

\


二、各自的优缺点是什么?

主要差异在于,Prim算法在面对稠密图时效率较高,Kruskal算法在面对稀疏图时效率更高。


三、具体代码

Prim算法:

#include <stdio.h>#include <stdlib.h>#define VISITED 1#define UNVISITED 0#define GRAPH_SIZE 6#define EDGE_MAXLENGTH 32767typedef struct EdgeCost{int cost, vex;};void Prim(int(*graph)[GRAPH_SIZE], EdgeCost *lowcost, int *visited);int main(){//记录被选出的点到达未被选出点的最小权值边//如:已选出点:v0,未被选出点:v1,v2,v3,v4,v5,则lowcost[4].cost代表v0到达v4的最小权值,lowcost[4].vex在此表示边的起点是v0EdgeCost lowcost[GRAPH_SIZE];//用于标记点是否被访问int visited[GRAPH_SIZE];//图int graph[GRAPH_SIZE][GRAPH_SIZE];int i, j;//初始化for (i = 0; i < GRAPH_SIZE; i++){visited[i] = 0;lowcost[i].cost = EDGE_MAXLENGTH;lowcost[i].vex = -1;}for (i = 0; i < GRAPH_SIZE; i++)for (j = 0; j < GRAPH_SIZE; j++)graph[i][j] = EDGE_MAXLENGTH;graph[0][1] = 7;graph[1][0] = 7;graph[0][2] = 1;graph[2][0] = 1;graph[0][3] = 5;graph[3][0] = 5;graph[2][1] = 5;graph[1][2] = 5;graph[2][3] = 5;graph[3][2] = 5;graph[2][4] = 8;graph[4][2] = 8;graph[2][5] = 4;graph[5][2] = 4;graph[1][4] = 3;graph[4][1] = 3;graph[3][5] = 2;graph[5][3] = 2;graph[4][5] = 6;graph[5][4] = 6;for (i = 0; i < GRAPH_SIZE; i++){for (j = 0; j < GRAPH_SIZE; j++)printf("%d\t", graph[i][j]);printf("\n");}printf("\n");//Prim算法,选择从v0开始visited[0] = VISITED;for (i = 1; i < GRAPH_SIZE; i++){if (graph[0][i] != EDGE_MAXLENGTH){lowcost[i].vex = 0;lowcost[i].cost = graph[0][i];}}Prim(graph, lowcost, visited);}void Prim(int(*graph)[GRAPH_SIZE], EdgeCost *lowcost, int *visited){int i, vex, adj, min = EDGE_MAXLENGTH, result = 0;for (i = 0; i < GRAPH_SIZE; i++){if (visited[i] != VISITED && lowcost[i].cost < min){adj = i;vex = lowcost[i].vex;min = lowcost[i].cost;}else if (visited[i] == VISITED)result++;}if (result == GRAPH_SIZE)return;visited[adj] = VISITED;printf("( %d, %d)   ", vex, adj);for (i = 0; i < GRAPH_SIZE; i++){if (graph[adj][i] < lowcost[i].cost){lowcost[i].vex = adj;lowcost[i].cost = graph[adj][i];}}Prim(graph, lowcost, visited);}

Kruskal算法:

<span style="font-size:12px;">#include <stdio.h>#include <stdlib.h>#define VISITED 1#define UNVISITED 0#define MAX_EDGES 20#define GRAPH_SIZE 6#define EDGE_MAXLENGTH 32767typedef struct Edge{int pre, back, weight;}Edge;int FindRoot(int *root, int point);void Kruscal(Edge *edges, int *root);int main(){Edge edges[MAX_EDGES];int root[GRAPH_SIZE];int graph[GRAPH_SIZE][GRAPH_SIZE];int i, j, k = 0;//初始化图for (i = 0; i < GRAPH_SIZE; i++)for (j = 0; j < GRAPH_SIZE; j++)graph[i][j] = EDGE_MAXLENGTH;graph[0][1] = 7;graph[1][0] = 7;graph[0][2] = 1;graph[2][0] = 1;graph[0][3] = 5;graph[3][0] = 5;graph[2][1] = 5;graph[1][2] = 5;graph[2][3] = 5;graph[3][2] = 5;graph[2][4] = 8;graph[4][2] = 8;graph[2][5] = 4;graph[5][2] = 4;graph[1][4] = 3;graph[4][1] = 3;graph[3][5] = 2;graph[5][3] = 2;graph[4][5] = 6;graph[5][4] = 6;//初始化可达的边集for (i = 0; i < GRAPH_SIZE; i++){for (j = 0; j < GRAPH_SIZE; j++){if (graph[i][j] < EDGE_MAXLENGTH){edges[k].pre = i;edges[k].back = j;edges[k].weight = graph[i][j];k++;}}}//初始化边的根节点数组for (i = 0; i < GRAPH_SIZE; i++)root[i] = 0;for (i = 0; i < GRAPH_SIZE; i++){for (j = 0; j < GRAPH_SIZE; j++)printf("%d\t", graph[i][j]);printf("\n");}printf("\n");Kruscal(edges, root);}int FindRoot(int *root, int point){while (root[point] > 0)point = root[point];return point;}void Kruscal(Edge *edges, int *root){int i, j, min, pre, back, visited, weight, buf, edf;for (i = 0; i < MAX_EDGES; i++){min = EDGE_MAXLENGTH;for (j = 0; j < MAX_EDGES; j++){if (edges[j].weight < min){pre = edges[j].pre;back = edges[j].back;min = edges[j].weight;visited = j;}}buf = FindRoot(root, pre);edf = FindRoot(root, back);edges[visited].weight = EDGE_MAXLENGTH;if (buf != edf){root[buf] = edf;printf("(%d, %d)", pre, back, min);}}}</span>


0 0
原创粉丝点击