Kurskal算法(克鲁斯卡尔算法)

特点:适用于稀疏图,边比较少的图。如果顶点较少,且为稠密图,则用Prim算法。跟Prim算法的用途相同。时间复杂度为O(e*loge),其中e为边数。

代码:

#include <stdio.h>
#include <stdlib.h>
#define MAXEDGE 20                          //设定边的最大值
#define INF 65535                           //用来设定边的最大值
typedef struct Edge
{
    int begin;
    int end;
    int weight;
}Edge;                                      //构建的边结点
typedef struct EGraph
{
    Edge edge[MAXEDGE];
    Edge EdgeSorted[MAXEDGE];
    int numGraphEdge;
}EGraph;                                    //构建的边集数组结构

static int Flag[MAXEDGE];                   //定义排序时各个顶点是否被比较过的状态,如果被比较过赋给EdgeSorted后,Flag = 1
void CreateEGraph(EGraph *G)                //构建一个操作的图
{ int i = 0,j = 0,k = 0,w = 0; printf("请输入图中边的数目:\n"); scanf("%d",&G->numGraphEdge); for(k = 0;k < G->numGraphEdge;k++) { printf("请输入边vi-vj的边的下标 i 和 j ,以及权重w :\n"); scanf("%d,%d,%d",&i,&j,&w); G->edge[k].begin = i; G->edge[k].end = j; G->edge[k].weight = w; } for(k = 0;k < G->numGraphEdge;k++) //初始化标示数组 { Flag[k] = 0; } } void SortEdge(EGraph *G) //对边集数组按权值大小进行排序 { int min,k,i,j; for(i = 0;i < G->numGraphEdge;i++) { min = INF; for(j = 0;j < G->numGraphEdge;j++) { if(Flag[j] == 0 && min >= G->edge[j].weight) { min = G->edge[j].weight; k = j; } } Flag[k] = 1; G->EdgeSorted[i].begin = G->edge[k].begin; G->EdgeSorted[i].end = G->edge[k].end; G->EdgeSorted[i].weight = G->edge[k].weight; } printf("\n*******************************\n"); printf("排序后的权值依次为:\n"); for(i = 0;i < G->numGraphEdge;i++) { printf("%d ",G->EdgeSorted[i].weight); } } int Find(int *parent,int f) //构造parent数组,为了判断最小生成树中是否构成了回路 { while(parent[f] > 0) //注意必须是while循环,直到parent[f]中的值为0,返回parent数组下标f { f = parent[f]; } return f; } //kurskal算法:依次遍历被排好序的边集数组,如果没有构成回路,就把他加入最小生成树,如果构成回路,则无视继续循环 void Kruskal(EGraph *G) { int i = 0,m,n; int parent[MAXEDGE]; for(i = 0;i < G->numGraphEdge;i++) { parent[i] = 0; } for(i = 0;i < G->numGraphEdge;i++) { m = Find(parent,G->EdgeSorted[i].begin); n = Find(parent,G->EdgeSorted[i].end); if(m != n) //说明没有形成环路 { parent[m] = n; printf("(%d,%d,%d) ",G->EdgeSorted[i].begin,G->EdgeSorted[i].end,G->EdgeSorted[i].weight); } } } int main() { EGraph G; //声明一个图 CreateEGraph(&G); //创建图 SortEdge(&G); printf("\n*******************************\n"); printf("\nkurskal得到的最小生成树的边为:\n"); Kruskal(&G); //打印由kurskal算法得到的最小生成树的各个边 printf("\n\n*******************************\n"); return 0; }

  

 

posted on 2014-12-22 15:56 BeatificDevin 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/devinblog/p/4178391.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
普里姆算法克鲁斯卡尔算法都是求解最小生成树的经典算法。 普里姆算法的基本思想是从一个点开始,每次选择一个与当前生成树距离最近的点加入生成树中,直到所有点都被加入生成树为止。具体实现时,可以使用一个优先队列来维护当前生成树与未加入生成树的点之间的距离,每次从队列中取出距离最小的点加入生成树中,并更新队列中其他点的距离。 以下是普里姆算法的Python实现: ```python import heapq def prim(graph): n = len(graph) visited = [False] * n dist = [float('inf')] * n dist[0] = 0 pq = [(0, 0)] mst = [] while pq: d, u = heapq.heappop(pq) if visited[u]: continue visited[u] = True mst.append(u) for v, w in graph[u]: if not visited[v] and w < dist[v]: dist[v] = w heapq.heappush(pq, (w, v)) return mst ``` 克鲁斯卡尔算法的基本思想是从所有边中选择权值最小的边加入生成树中,直到生成树中包含所有点为止。具体实现时,可以使用并查集来维护当前生成树中的连通性,每次从所有边中选择权值最小的边,如果这条边连接的两个点不在同一个连通块中,则将这条边加入生成树中。 以下是克鲁斯卡尔算法的Python实现: ```python def kruskal(graph): n = len(graph) parent = list(range(n)) rank = [0] * n edges = [] for u in range(n): for v, w in graph[u]: edges.append((w, u, v)) edges.sort() mst = [] for w, u, v in edges: pu, pv = find(parent, u), find(parent, v) if pu != pv: mst.append((u, v, w)) union(parent, rank, pu, pv) return mst def find(parent, u): if parent[u] != u: parent[u] = find(parent, parent[u]) return parent[u] def union(parent, rank, pu, pv): if rank[pu] > rank[pv]: parent[pv] = pu elif rank[pu] < rank[pv]: parent[pu] = pv else: parent[pu] = pv rank[pv] += 1 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值