zoukankan      html  css  js  c++  java
  • 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("请输入图中边的数目: "); scanf("%d",&G->numGraphEdge); for(k = 0;k < G->numGraphEdge;k++) { printf("请输入边vi-vj的边的下标 i 和 j ,以及权重w : "); 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(" ******************************* "); printf("排序后的权值依次为: "); 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(" ******************************* "); printf(" kurskal得到的最小生成树的边为: "); Kruskal(&G); //打印由kurskal算法得到的最小生成树的各个边 printf(" ******************************* "); return 0; }

      

  • 相关阅读:
    深入理解JUC:第五章:CyclicBarrier循环栅栏
    技术汇总:第十八章:枚举的简单使用
    深入理解JUC:第四章:CountDownLatch倒计时器
    java锁:第四章:读写锁
    java锁:第三章:自旋锁
    java锁:第二章:可重入锁和递归锁
    java锁:第一章:公平和非公平锁
    集合线程安全问题:第一章:集合类不安全之并发修改异常
    深入理解JUC:第一章:volatile的三大特性
    深入理解JUC:第二章:CAS:CompareAndSwap底层原理
  • 原文地址:https://www.cnblogs.com/devinblog/p/4178391.html
Copyright © 2011-2022 走看看