最小生成树(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更新状态如下图:
    最小生成树(Prim算法)_第1张图片

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

  5. 代码如下:

#include 
#include 
#include 
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;
}

你可能感兴趣的:(数据结构和算法,考研算法,最小生成树)