导航

C++实现最小生成树_普利姆算法

#include <iostream>
#include <iomanip>
#define int_max 5000
#define max_ver 20
typedef enum { dg, dn, udg, udn } graphkind;
typedef struct arccell
{
    int adj;
    //infotype *info;
}arc, adjmat[max_ver][max_ver];
typedef struct
{
    char vexs[max_ver];
    adjmat arcs;
    int vexnum, arcnum;
    graphkind kind;
}mgraph;

typedef struct
{
    char adjvex;
    int lowcost;
}closedge[max_ver];

using namespace std;


int locatevex(mgraph g, char v)
{
    int i;
    for (i = 0; i < g.vexnum; i++)
    {
        if (g.vexs[i] == v) return i;
    }
    return -1;
}

int minmum(closedge closedge, int ma)
{
    int mi = int_max, mi_i = -1;
    for (int i = 0; i < ma; i++)
    {
        if (closedge[i].lowcost != 0)
        {
            if (mi > closedge[i].lowcost)
            {
                mi = closedge[i].lowcost;
                mi_i = i;
            }

        }
    }
    return mi_i;
}

void createudn(mgraph& g)
{
    char v1, v2;
    int m, i, j, k;
    cout << "请输入图的顶点个数和边数:";
    cin >> g.vexnum >> g.arcnum;
    cout << "请输入各顶点所代表的字符:";
    for (i = 0; i < g.vexnum; i++)
        cin >> g.vexs[i];
    for (i = 0; i < g.vexnum; i++)
        for (j = 0; j < g.vexnum; j++)
            g.arcs[i][j].adj = int_max;
    for (k = 0; k < g.arcnum; k++)
    {
        cout << "请输入起点(字符)和终点(字符)及其对应的边的权值:";
        cin >> v1 >> v2 >> m;
        i = locatevex(g, v1);
        j = locatevex(g, v2);
        g.arcs[i][j].adj = m;
        g.arcs[j][i] = g.arcs[i][j];
    }
    cout << "图的邻接矩阵为:" << endl;
    for (i = 0; i < g.vexnum; i++)
    {
        for (j = 0; j < g.vexnum; j++)
            cout << setw(5) << g.arcs[i][j].adj << "   ";
        cout << endl;
    }

    return;
}

void prim(mgraph g, char u)
{
    int i, k, j;
    closedge closedge;
    k = locatevex(g, u);
    for (j = 0; j < g.vexnum; j++)
        if (j != k)
        {
            closedge[j].adjvex = u;
            closedge[j].lowcost = g.arcs[k][j].adj;
        }
    closedge[k].lowcost = 0;
    cout << "最小生成树为:" << endl;
    for (i = 1; i < g.vexnum; i++)
    {
        k = minmum(closedge, g.vexnum);
        cout << closedge[k].adjvex << "->" << g.vexs[k] << " 权值 :" << closedge[k].lowcost << endl;
        closedge[k].lowcost = 0;
        for (j = 0; j < g.vexnum; j++)
            if (g.arcs[k][j].adj < closedge[j].lowcost)
            {
                closedge[j].adjvex = g.vexs[k];
                closedge[j].lowcost = g.arcs[k][j].adj;
            }
    }
}

int main()
{
    mgraph g;
    char u;
    cout << "开始构造无向图" << endl;
    createudn(g);
    cout << "运用普利姆编程思想生成二叉树" << endl;
    while (1)
    {
        cout << "请输入最小生成树的起点(输入0退出):";
        cin >> u;
        if (u == '0') return 0;
        else
        {
            int i;
            for (i = 0; i < g.vexnum; i++)
            {
                if (g.vexs[i] == u) break;
            }
            if (i == g.vexnum) cout << "您输入的字符有误,请重新输入!" << endl;
            else prim(g, u);
        }
    }
    return 0;
}

  

posted on 2021-10-14 15:47    阅读(68)  评论(0)    收藏  举报