最小生成树(Prim算法)

  1. 算法思路:
    采用Prim算法进行输出最小生成树,VNode数组记录有更小权值边连接的顶点,每次有结点加入集合中进行一次更新(检查新加入的元素对于之前集合是否有更小的权值到达未在集合中的顶点),lowCost记录最小权值,赋值为0代表元素加入集合。

  2. 测试数据
    G->edges[0][1] = 34; G->edges[1][0] = 34;
    G->edges[0][2] = 46; G->edges[2][0] = 46;
    G->edges[0][5] = 19; G->edges[5][0] = 19;
    G->edges[1][4] = 12; G->edges[4][1] = 12;
    G->edges[2][3] = 17; G->edges[3][2] = 17;
    G->edges[2][5] = 25; G->edges[5][2] = 25;
    G->edges[3][5] = 25; G->edges[5][3] = 25;
    G->edges[3][4] = 38; G->edges[4][3] = 38;
    G->edges[4][5] = 26; G->edges[5][4] = 26;

  3. VNode和lowcost更新状态如下图:
    在这里插入图片描述

  4. 输出数据为:
    (3,2)17
    (3,5)25
    (5,0)19
    (5,4)26
    (4,1)12

  5. 代码如下:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

#define MaxSize 10
#define INF 99999

typedef struct{
    char data;
} VerNode;

typedef struct{
    int edges[MaxSize][MaxSize];
    VerNode VerType[MaxSize];
    int n;
    int e;
}MGraph;

void InitMGraph(MGraph* G){
    G->e = 9;
    G->n = 6;
    for (int i = 0; i < G->n; i++) {
        for (int j = 0; j < G->n; j++) {
            G->edges[i][j] = INF;
        }
    }
    G->edges[0][1] = 34;  G->edges[1][0] = 34;
    G->edges[0][2] = 46;  G->edges[2][0] = 46;
    G->edges[0][5] = 19;  G->edges[5][0] = 19;
    G->edges[1][4] = 12;  G->edges[4][1] = 12;
    G->edges[2][3] = 17;  G->edges[3][2] = 17;
    G->edges[2][5] = 25;  G->edges[5][2] = 25;
    G->edges[3][5] = 25;  G->edges[5][3] = 25;
    G->edges[3][4] = 38;  G->edges[4][3] = 38;
    G->edges[4][5] = 26;  G->edges[5][4] = 26;
}

void Prim(MGraph* G,int currentNode){
    //记录权值
    int lowcost[MaxSize];
    //记录有更小权值边连接的顶点
    int vset[MaxSize];
    //记录currentnode到达其他顶点的q权值
    int minIndex;
    for (int i = 0; i < G->n; i++) {
        lowcost[i] = G->edges[currentNode][i];
        vset[i] = currentNode;
    }
    //赋值为0时表示已加入了集合中
    lowcost[currentNode] = 0;
    
    for (int i = 0; i < G->n-1; i++) {
        int min = INF;
        //寻找最小权值
        for (int j = 0; j < G->n; j++) {
            if (lowcost[j]!=0 && lowcost[j] < min) {
                min = lowcost[j];
                minIndex = j;
            }
        }
        cout<<endl<<"("<<vset[minIndex]<<","<<minIndex<<")"<<min<<endl;

        //把最小权值所在顶点加入集合中
        lowcost[minIndex] = 0;
        
        //更新新集合到其他元素的权值,有更小的权值能到达,则需更小,Vset记录相应边的i顶点
        for (int k = 0; k < G->n; k++) {
            if (lowcost[k] != 0 &&  G->edges[minIndex][k] < lowcost[k]) {
                lowcost[k] = G->edges[minIndex][k];
                vset[k] = minIndex;
            }
        }
    }
}

int main(int argc, const char * argv[]) {
    MGraph* G = new MGraph();
    InitMGraph(G);
    Prim(G, 3);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值