prim算法的实现

添加链接描述
运行了一下prim 算法 觉得这个程序还可以 后期可以在此基础上做较大的改动 故此分享了这个代码

#include <stdio.h>
#define MAXVEX 10
#define TRUE 1
#define FALSE 0
#define INF 65535//此处是权值极大值
#define LENGTH(a) (sizeof(a) / sizeof(a[0]))

typedef char VertexType;

typedef struct
{
    VertexType vexs[MAXVEX];//存储顶点信息
    int arc[MAXVEX][MAXVEX];//邻接矩阵
    int numVertexes, numEdges;//边数和点数
}MGraph;
//创建一个图
void CreateMGraphExample(MGraph *G)
{
    VertexType vexs[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8'};//存储的顶点
    int arc[][9] = {
            {0, 10, INF, INF, INF, 11, INF, INF, INF},
            {10, 0, 18, INF, INF, INF, 16, INF, 12},
            {INF, 18, 0, 22, INF, INF, INF, INF, 8},
            {INF, INF, 22, 0, 20, INF, INF, 16, 21},
            {INF, INF, INF, 20, 0, 26, INF, 7, INF},
            {11, INF, INF, INF, 26, 0, 17, INF, INF},
            {INF, 16, INF, INF, INF, 17, 0, 19, INF},
            {INF, INF, INF, 16, 7, INF, 19, 0, INF},
            {INF, 12, 8, 21, INF, INF, INF, INF, 0}
    };

    G->numVertexes = LENGTH(vexs);//顶点数赋值
    G->numEdges = 0;

    for(int i = 0; i < G->numVertexes; i++)
        G->vexs[i] = vexs[i];//给图的顶点数组赋值
    for(int i = 0; i < G->numVertexes; i++)
    {
        for(int j = 0; j < G->numVertexes; j++)
        {
            G->arc[i][j] = arc[i][j];//给图的邻边矩阵赋值
        }
    }

    for(int i = 0; i < G->numVertexes; i++)
    {
        for(int j = 0; j < G->numVertexes; j++)
        {
            if(i != j && G->arc[i][j] != INF)
            {
                G->numEdges++;//统计图中出现的边数  因为是无向图 这里是二倍的关系
            }
        }
    }

    printf("%d %d\n", G->numVertexes, G->numEdges / 2);//这里在计算图的边数的时候 除了2 

}
//这里是可以手动创建图的函数
//由于上面的函数给了示例   如果想要自己手动输入函数  可以在这里修改
void CreateMGraph(MGraph *G)/* 构件图 */
{
    int i, j;

    /* printf("请输入边数和顶点数:"); */
    G->numEdges=15;
    G->numVertexes=9;

    for (i = 0; i < G->numVertexes; i++)/* 初始化图 */
    {
        for ( j = 0; j < G->numVertexes; j++)
        {
            if (i==j)
                G->arc[i][j]=0;
            else
                G->arc[i][j] = G->arc[j][i] = INF;
        }
    }

    G->arc[0][1]=10;
    G->arc[0][5]=11;
    G->arc[1][2]=18;
    G->arc[1][8]=12;
    G->arc[1][6]=16;
    G->arc[2][8]=8;
    G->arc[2][3]=22;
    G->arc[3][8]=21;
    G->arc[3][6]=24;
    G->arc[3][7]=16;
    G->arc[3][4]=20;
    G->arc[4][7]=7;
    G->arc[4][5]=26;
    G->arc[5][6]=17;
    G->arc[6][7]=19;

    for(i = 0; i < G->numVertexes; i++)
    {
        for(j = i; j < G->numVertexes; j++)//注意 这里j的起点是从i开始的
        {
            G->arc[j][i] =G->arc[i][j];//因为是无向图 所以顶点具有对称性
        }
    }

}

/* Prim 算法生成最小生成树 */
void MiniSpanTree_Prim(MGraph G)
{
    int min, i, j, k;  // min 为当前权值最小值
    int lowcost[MAXVEX];  /* 保存顶点间边的权值 */
    int adjvex[MAXVEX];   /* 保存相关顶点的下标,即下标与其值所连边为当前最小权值边 */
    lowcost[0] = 0;  /* 选取第一个顶点为起始点, 即 v0 加入树, lowcost的值为0,在这里就是此下标的顶点已经加入生成树 */
    adjvex[0] = 0;   /* 初始化第一个顶点下标为0 */
    for(i = 1; i < G.numVertexes; i++)  /* 循环除下标为 0 外的全部顶点 */
    {
        lowcost[i] = G.arc[0][i];  /* 将与 v0 顶点有边的权值存入数组   就是遍历所有与v0相邻的边*/
        adjvex[i] = 0;  /* 将其他所有顶点的值初始化为 v0 的下标 */
    }
    for(i = 1; i < G.numVertexes; i++)
    {
        min = INF;   /* 初始化最小权值为 无穷大 */
        j = 1, k = 0;//因为我们一开始是从0开始的 所以这里的j改成了从1开始
        while(j < G.numVertexes)  /* 循环全部顶点,寻找当前最小生成树顶点集合中最小权值的边 */
        {
            if(lowcost[j] != 0 && lowcost[j] < min)  /* 如果权值不为 0(即不在树中),这!=0的意思就是这个顶点还没有放到树中  且权值小于 min */
            {
                min = lowcost[j];  /* 则让当前权值成为最小值 */
                k = j;             /* 将当前最小值的下标存入k */
            }
            j++;
        }
        lowcost[k] = 0;  /* 将当前顶点的权值设置为0, 表示此顶点已加入树的顶点集合  取k位置的顶点 并将其加入到树中去 */
        printf("(%d, %d)", adjvex[k], k);  /* 打印当前顶点边中权值最小的边 */
        for(j = 1; j < G.numVertexes; j++)  /* 循环所有顶点 */
        {
            /* 如果下标为 k 的顶点边集中权值小于已存在的权值, 比如 (v0, v6)权值为INF, 而(v1, v6)权值为 16, 更新*/
            if(lowcost[j] != 0 && G.arc[k][j] < lowcost[j])
            {
                lowcost[j] = G.arc[k][j];  /* 将较小的权值存入 lowcost 相应位置 */
                adjvex[j] = k;   /* 将下标为 k 的顶点存入 adjvex */
            }
        }
    }
}

int main() {
    MGraph G;
    CreateMGraphExample(&G);
//    CreateMGraph(&G);
    MiniSpanTree_Prim(G);
    printf("Hello, World!\n");
    return 0;
}


这是运行的结果

9 14
(0, 1)(0, 5)(1, 8)(8, 2)(1, 6)(6, 7)(7, 4)(7, 3)Hello, World!

关于prim算法的知识请查阅书本!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值