[数据结构]最小生成树

最小生成树:构造连通网的最小代价生成树

1、Prim算法

  Prim算法从图的顶点的方向出发,首先确定一个顶点,找到该顶点到任意其他顶点的连通代价,然后根据新确定的节点更新到下一个节点的连通代价。

  数据结构声明:

  

struct Graph
{
    int vertexes[MAX];
    int arc[MAX][MAX];
    int sum_vertexes,sum_edges;
};

构造图:

void createGraph(Graph &graph)
{
    memset(graph.arc,0,sizeof(graph.arc));
    int x,y,weight;
    cout<<"输入顶点的总数"<<endl;
    cin>>graph.sum_vertexes;
    cout<<"输入边的总数"<<endl;
    cin>>graph.sum_edges;
    for(int i=0; i<graph.sum_vertexes; i++)
    {
        cout<<"输入第"<<i+1<<"个顶点的标识"<<endl;
        cin>>graph.vertexes[i];
    }
    for(int i=0; i<graph.sum_edges; i++)
    {
        cout<<"输入第"<<i+1<<"条边的起点 终点 权重"<<endl;
        cin>>x>>y>>weight;
        graph.arc[x][y]=graph.arc[y][x]=weight;
    }
}
Prim算法:

void Prim(Graph graph)
{
    int adjvex[MAX];
    int lowcost[MAX];
    lowcost[0]=-1;
    adjvex[0]=0;
    //初始化
    for(int i=1; i<graph.sum_vertexes; i++)
    {
        lowcost[i]=graph.arc[0][i];
        adjvex[i]=0;
    }
    //lowcost :-1表示顶点已经访问,0表示两顶点不相连,其他表示权重
    for(int i=1; i<graph.sum_vertexes; i++)
    {
        //权重<65535
        int min=65535;
        int k;
        for(int j=1; j<graph.sum_vertexes; j++)
        {
            if(lowcost[j]!=-1&&lowcost[j]!=0&&lowcost[j]<min)
            {
                min=lowcost[j];
                k=j;
            }
        }
        lowcost[k]=-1;
        cout<<adjvex[k]<<"   "<<k<<endl;
        //更新lowcost和adjvex
        for(int j=1; j<graph.sum_vertexes; j++)
        {
            if(lowcost[j]!=-1&&graph.arc[k][j]!=0&&(graph.arc[k][j]<lowcost[j]||lowcost[j]==0))
            {
                    lowcost[j]=graph.arc[k][j];
                    adjvex[j]=k;
            }
        }
    }
}

2、Kruskal算法

  Prim算法从定点出发,Kruskal则从边的方向考虑,将图的每一条边按照连通代价按照从小到大的方式排序,然后一次将边加入到结果中,为了避免形成环,加入一个判断机制。

数据结构声明:

struct  Edge
{
    int start;
    int stop;
    int weight;
};

struct Graph
{
    Edge edge[MAX];
    int sum_edges;
};

构造图:

void createGraph(Graph &graph)
{
    int x,y,w;
    cout<<"输入边的总数"<<endl;
    cin>>graph.sum_edges;
    for(int i=0;i<graph.sum_edges;i++)
    {
        cout<<"输入第"<<i+1<<"条边的起点 终点 权重"<<endl;
        cin>>x>>y>>w;
        graph.edge[i].start=x;
        graph.edge[i].stop=y;
        graph.edge[i].weight=w;
    }
}

Kruskal算法

void sortEdges(Graph &graph)
{
    Edge temp;
    for(int i=0;i<graph.sum_edges;i++)
    {
        for(int j=i+1;j<graph.sum_edges;j++)
        {
            if(graph.edge[i].weight>graph.edge[j].weight)
            {
                temp=graph.edge[i];
                graph.edge[i]=graph.edge[j];
                graph.edge[j]=temp;
            }
        }
    }
}

int Find(int *parent,int t)
{
    while(parent[t]!=0)
        t=parent[t];
    return t;
}

void Kruskal(Graph graph)
{
    int m,n;
    int parent[MAX];
    //初始化
    for(int i=0;i<graph.sum_edges;i++)
        parent[i]=0;
    for(int i=0;i<graph.sum_edges;i++)
    {
            m=Find(parent,graph.edge[i].start);
            n=Find(parent,graph.edge[i].stop);
            if(m!=n)
            {
                parent[m]=n;
                cout<<graph.edge[i].start<<"   "<<graph.edge[i].stop<<"   "<<graph.edge[i].weight<<endl;
            }
    }
}

还是写代码想让图中两个不连通的顶点之间的连通代价用0表示,结果在实现的判断中就要多添加一些条件判断,如果使用正无穷大的话,就方便多了~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值