数据结构之C++实现最小生成树克鲁斯卡尔(Kruskal)算法

数据结构之C++实现最小生成树克鲁斯卡尔(Kruskal)算法

#include <iostream>
#include <cstdlib>
#include <cmath>
#include <ctime>
using namespace std;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
#define MAXEDGE 20
#define MAXVEX 20
#define GRAPH_INFINITY 65535
typedef struct
{
    int begin;
    int end;
    int weight;
}Edge;   /* 对边集数组Edge结构的定义 */
class MGraph
{
public:
    MGraph();
    ~MGraph();
    void CreateMGraph(void);
    /* 交换权值 以及头和尾 */
    void Swapn(int i, int j);
    /* 对权值进行排序 */
    void sort(void);
    /* 查找连线顶点的尾部下标 */
    int Find(int f);
    /* 生成最小生成树 */
    void MiniSpanTree_Kruskal(void);
private:
    int arc[MAXVEX][MAXVEX];
    int numVertexes, numEdges;
    Edge* edges=new Edge[MAXEDGE];/* 定义边集数组,edge的结构为begin,end,weight,均为整型 */
    int parent[MAXVEX];/* 定义一数组用来判断边与边是否形成环路 */
};
MGraph::MGraph()
{
    numVertexes=0;
    numEdges=0;
    for(int i=0;i<MAXVEX;i++)
    {
        for(int j=0;j<MAXVEX;j++)
        {
            if (i==j) arc[i][j]=0;
            else arc[i][j]=GRAPH_INFINITY;
        }
    }
    //for(int i=0;i<MAXEDGE;i++) edges[i]=new Edge;

}
MGraph::~MGraph()
{
    delete [] edges;
}
void MGraph::CreateMGraph(void)
{
    int i, j;
    /* printf("请输入边数和顶点数:"); */
    numEdges=15;
    numVertexes=9;

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

    for(i = 0; i < numVertexes; i++)
    {
        for(j = i; j < numVertexes; j++)
        {
            arc[j][i] =arc[i][j];
        }
    }

}
void MGraph::Swapn(int i,int j)
{
    int temp;
    temp = edges[i].begin;
    edges[i].begin = edges[j].begin;
    edges[j].begin = temp;
    temp = edges[i].end;
    edges[i].end = edges[j].end;
    edges[j].end = temp;
    temp = edges[i].weight;
    edges[i].weight = edges[j].weight;
    edges[j].weight = temp;
}
void MGraph::sort(void)
{
    int i, j;
    //排序算法
    for(i=0;i<numEdges;i++)
    {
        for (j=i+1;j<numEdges;j++)
        {
            if(edges[i].weight>edges[j].weight)
            {
                Swapn(i,j);
            }
        }
    }
    cout<<"权排序之后的为:"<<endl;
    for(i=0; i<numEdges;i++)
    {
        cout<<"("<<edges[i].begin<<","<<edges[i].end<<") "<<edges[i].weight<<endl;;
    }
}
int MGraph::Find(int f)
{
    while(parent[f] > 0)
    {
        f = parent[f];
    }
    return f;
}
void MGraph::MiniSpanTree_Kruskal(void)
{
    int i, j, n, m;
    int k = 0;

    /* 用来构建边集数组并排序********************* */
    for ( i = 0; i < numVertexes-1; i++)
    {
        for (j = i + 1; j < numVertexes; j++)
        {
            if (arc[i][j]<GRAPH_INFINITY)
            {
                edges[k].begin = i;
                edges[k].end = j;
                edges[k].weight = arc[i][j];
                k++;
            }
        }
    }
    sort();
    /* ******************************************* */

    for (i = 0; i < numVertexes; i++)
        parent[i] = 0;  /* 初始化数组值为0 */
    cout<<"打印最小生成树:"<<endl;
    for (i = 0; i < numEdges; i++)    /* 循环每一条边 */
    {
        n = Find(edges[i].begin);
        m = Find(edges[i].end);
        if (n != m) /* 假如n与m不等,说明此边没有与现有的生成树形成环路 */
        {
            parent[n] = m;  /* 将此边的结尾顶点放入下标为起点的parent中。 */
                            /* 表示此顶点已经在生成树集合中 */
            cout<<"("<<edges[i].begin<<","<<edges[i].end<<")  "<<edges[i].weight<<endl;
        }
    }   
}
int main()
{
    MGraph* G=new MGraph;
    G->CreateMGraph();
    G->MiniSpanTree_Kruskal();
    delete G;
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早茶&&月光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值