克鲁斯卡尔算法(贪心策略)最小生成树(NJAU 网工)

核心思想当然不是我的,

我只是实现而已;


#include<stdafx.h>
#include<string>
#include<iostream>
using namespace std;
#include<fstream>
#include<stdio.h>


#define MAX_VEX_NUM 50
typedef char VertexType;
typedef enum {
DG, UDG
} GraphType;




typedef struct
{
int num;
int weight;
}Arcs;


typedef struct {
VertexType vexs[MAX_VEX_NUM];
int arcs[MAX_VEX_NUM][MAX_VEX_NUM];
int vexnum, arcnum;
GraphType type;
} MGraph;


int getIndexOfVexs(char vex, MGraph *MG)
{
int i;
for (i = 1; i <= MG->vexnum; i++)
{
if (MG->vexs[i] == vex)
{
return i;
}
}
return 0;
}


void create_MG(MGraph *MG)
{


int i, j, k;
int v1, v2, type;
char c1, c2;
//printf("Please input graph type DG(0) or UDG(1) :");
//scanf("%d", &type);
type = 1;//默认无向图
if (type == 0)
MG->type = DG;
else if (type == 1)
MG->type = UDG;
else
{
printf("Please input correct graph type DG(0) or UDG(1)!");
return;
}

ifstream fp("data.txt");//
char line[100];
fp.getline(line, 100);
int num=stoi(line,0,10);
MG->vexnum = num;
fp.getline(line, 100);
num = stoi(line, 0, 10);
MG->arcnum = num;
//printf("Please input vexmun : ");
//scanf("%d", &MG->vexnum);//读入节点数目


//printf("Please input arcnum : ");
//scanf("%d", &MG->arcnum);//读入边的数目
//getchar();
for (i = 1; i <= MG->vexnum; i++)
{
//printf("Please input %dth vex(char):", i);
//scanf("%c", &MG->vexs[i]);//读入节点字符
//getchar();
fp.getline(line,100);
MG->vexs[i] = line[0];
}


//初始化邻接矩阵
for (i = 1; i <= MG->vexnum; i++)
{
for (j = 1; j <= MG->vexnum; j++)
{
MG->arcs[i][j] = 0;
}
}


//输入边的信息,建立邻接矩阵
for (k = 1; k <= MG->arcnum; k++) {
//printf("Please input %dth arc v1(char) v2(char) : ", k);
//scanf("%c %c", &c1, &c2);
fp.getline(line,100);
c1 = line[0];
c2 = line[1];
fp.getline(line, 100);
int num = stoi(line,0,10);
v1 = getIndexOfVexs(c1, MG);
v2 = getIndexOfVexs(c2, MG);
if (MG->type == 1)
MG->arcs[v1][v2] = MG->arcs[v2][v1]= num;
else
MG->arcs[v1][v2] = num;
//getchar();
}
fp.close();
}


void print_MG(MGraph MG)
{
int i, j;
if (MG.type == DG)
{
printf("Graph type : Direct graph:\n");
}
else
{
printf("Graph type: Undirect graph:\n");
}
printf("Graph vertex number: %d \n", MG.vexnum);
printf("Graph arc number: %d \n", MG.arcnum);


printf("Vertex set:");
for (i = 1; i <= MG.vexnum; i++)
printf("%c   ", MG.vexs[i]);
printf("\n");
printf("Adjacency Matrix:\n");


for (i = 1; i <= MG.vexnum; i++)
{
j = 1;
for (; j < MG.vexnum; j++)
{
printf("%d   ", MG.arcs[i][j]);
}
printf("%d   ", MG.arcs[i][j]);
printf("\n");
}
}


typedef struct
{
int begin;
int end;
int weight;
}Item;


typedef struct
{
Item items[100];
int arcnum;
int vexnum;
}AGraph;


void createArcsArray(MGraph g,AGraph &ag)
{
ag.arcnum = g.arcnum;
ag.vexnum = g.vexnum;
int k = 0;
for (int i=1;i<=g.vexnum;i++)
{
for (int j=i;j<=g.vexnum;j++)
{
if (g.arcs[i][j]==0)//权值为零,就是没边,跳过
{
continue;
}
ag.items[k].begin = i;
ag.items[k].end = j;
ag.items[k].weight = g.arcs[i][j];
k++;
}
}
//then sort them
//写一个冒泡排序吧

for (int i=0;i<ag.arcnum;i++)
{
for (int j=i;j<ag.arcnum;j++)
{
if (ag.items[i].weight>ag.items[j].weight)
{
Item temp;
temp = ag.items[i];
ag.items[i] = ag.items[j];
ag.items[j] = temp;
}
}
}

}


void printAG(AGraph ag)
{
cout << endl << endl;
cout << ag.arcnum << endl;
for (int i=0;i<ag.arcnum;i++)
{
cout << ag.items[i].begin << " " << ag.items[i].end << " " << ag.items[i].weight << endl;
}
}


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


void miniTree(AGraph G)
{
int i, n, m;
int parent[50];
for (i=0;i<G.vexnum;i++)
{
parent[i] = 0;
}
for (i=0;i<G.arcnum;i++)
{
n = Find(parent,G.items[i].begin);
m = Find(parent, G.items[i].end);
if (n!=m)
{
parent[n] = m;
printf("(%d,%d),%d \n",G.items[i].begin, G.items[i].end, G.items[i].weight);
}
}
}
int main()
{


MGraph MG;
AGraph AG;
create_MG(&MG);
createArcsArray(MG,AG);
print_MG(MG);
printAG(AG);
miniTree(AG);
system("pause");
return 0;

}


下面是数据文本的结构

4
4
a
b
c
d
ab
10
ac
20
ad
22
bc
12




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值