#include<iostream>
using namespace std;
const int MAX = 15; //数组最大容量
struct Edge
{
int begin;
int end;
int weight;
};
class Graph
{
private:
int vertex_num; //顶点数
int edge_num; //边数
Edge edges[MAX]; //边集数组
char vertex[MAX]; //顶点数组
int parent[MAX]; //定义一组数组用来判断边与边是否形成回路
int locate(char ch); //定位
void sort(Edge *edges); //排序
int find_root(int *parent, int node); //查找根结点
public:
Graph(int v, int e); //创建邻接矩阵
void kruskal(); //kruskal算法
};
//定位
int Graph::locate(char ch)
{
int i = 0;
for (; i < this->vertex_num; i++)
{
if (this->vertex[i] == ch)
{
break;
}
}
return i;
}
//构造函数
Graph::Graph(int v, int e) : vertex_num(v), edge_num(e)
{
//输入图中顶点
cout << "请输入这" << this->vertex_num << "个顶点:" << endl;
for (int i = 0; i < this->vertex_num; i++)
{
cin >> this->vertex[i];
}
//初始化parent数组
for (int i = 0; i < this->vertex_num; i++)
{
this->parent[i] = -1; //顶点初始化全部为根结点,-1表示没有双亲结点
}
//构造边集数组
cout << "请输入两个顶点及其权值:" << endl;
for (int i = 0; i < this->edge_num; i++)
{
char first, second;
cin >> first >> second >> edges[i].weight;
edges[i].begin = this->locate(first);
edges[i].end = this->locate(second);
}
}
//冒泡排序(将边集数组按权值从小到大排序)
void Graph::sort(Edge *edge)
{
for (int i = 0; i < this->edge_num - 1; i++)
{
for (int j = 0; j < this->edge_num - i - 1; j++)
{
if (edges[j].weight > edges[j + 1].weight)
{
//交换权值
int temp1, temp2, temp3;
temp1 = edges[j + 1].weight;
edges[j + 1].weight = edges[j].weight;
edges[j].weight = temp1;
//交换begin
temp2 = edges[j + 1].begin;
edges[j + 1].begin = edges[j].begin;
edges[j].begin = temp2;
//交换end
temp3 = edges[j + 1].end;
edges[j + 1].end = edges[j].end;
edges[j].end = temp3;
}
}
}
}
//查找根
int Graph::find_root(int *parent, int node)
{
while (this->parent[node] > -1)
{
node = this->parent[node];
}
return node;
}
//kruskal算法
void Graph::kruskal()
{
int i, m, n;
//为边集数组按照权值从小到大排序
this->sort(this->edges);
//循环每一条边
for (i = 0; i < this->edge_num; i++)
{
//找到根结点
n = this->find_root(this->parent, this->edges[i].begin);
m = this->find_root(this->parent, this->edges[i].end);
//如果n不等于m,说明此边没有与现有的生成树形成环路
if (n != m)
{
//将此边的纳入生成树
this->parent[n] = m;
//打印最小生成树的两个顶点及其权值
cout << "("
<< this->vertex[this->edges[i].begin]
<< ","
<< this->vertex[this->edges[i].end]
<< ")\t权值为:"
<< this->edges[i].weight << endl;
}
}
}
int main()
{
int v = 0, e = 0;
cout << "请输入图的顶点数和边数:" << endl;
cin >> v >> e;
Graph g(v, e);
cout << "最小生成树:" << endl;
g.kruskal();
system("pause");
return 0;
}
c++实现kruskal算法(最小生成树)
最新推荐文章于 2025-05-13 09:34:35 发布