#include <iostream>
#include <vector>
#include <queue>
#include <functional>
#include <limits>
using namespace std;
// 图的邻接表表示
struct ArcNode {
int adjVex; // 该弧所指向的顶点的位置
int weight; // 权重
ArcNode* next; // 指向下一条弧的指针
};
struct VNode {
char data; // 顶点信息
ArcNode* firstArc; // 指向第一条依附该顶点的弧的指针
};
struct ALGraph {
int vexNum, arcNum; // 图的当前顶点数和弧数
VNode vertices[100]; // 顶点表
};
// 并查集节点
struct UFSNode {
int parent;
int rank;
};
// 并查集
struct UFSet {
UFSNode* nodelist;
int length;
};
// 优先队列元素
struct Edge {
int u, v;
int weight;
};
// 最小堆优先队列
struct Compare {
bool operator()(const Edge& a, const Edge& b) {
return a.weight > b.weight;
}
};
// 初始化并查集
void InitUFSet(UFSet& S, int size) {
S.nodelist = new UFSNode[size];
S.length = size;
for (int i = 0; i < size; ++i) {
S.nodelist[i].parent = i;
S.nodelist[i].rank = 0;
}
}
// 查找根节点
int UFSetFind(UFSet& S, int x) {
if (S.nodelist[x].parent != x) {
S.nodelist[x].parent = UFSetFind(S, S.nodelist[x].parent);
}
return S.nodelist[x].parent;
}
// 合并集合
void UFSetUnion(UFSet& S, int x, int y) {
int rootX = UFSetFind(S, x);
int rootY = UFSetFind(S, y);
if (rootX != rootY) {
if (S.nodelist[rootX].rank > S.nodelist[rootY].rank) {
S.nodelist[rootY].parent = rootX;
} else if (S.nodelist[rootX].rank < S.nodelist[rootY].rank) {
S.nodelist[rootX].parent = rootY;
} else {
S.nodelist[rootY].parent = rootX;
S.nodelist[rootX].rank++;
}
}
}
// 初始化最小优先队列
void InitMinPriorityQueue(priority_queue<Edge, vector<Edge>, Compare>& Q) {
while (!Q.empty()) Q.pop();
}
// 将元素压入优先队列
void MinPriorityQueuePush(priority_queue<Edge, vector<Edge>, Compare>& Q, const Edge& e) {
Q.push(e);
}
// 从优先队列弹出元素
void MinPriorityQueuePop(priority_queue<Edge, vector<Edge>, Compare>& Q, Edge& e) {
if (!Q.empty()) {
e = Q.top();
Q.pop();
}
}
// Kruskal算法求最小生成树
void MST_Kruskal(ALGraph& G) {
UFSet S;
InitUFSet(S, G.vexNum);
priority_queue<Edge, vector<Edge>, Compare> Q;
InitMinPriorityQueue(Q);
for (int i = 0; i < G.vexNum; ++i) {
for (ArcNode* p = G.vertices[i].firstArc; p != nullptr; p = p->next) {
Edge e = {i, p->adjVex, p->weight};
MinPriorityQueuePush(Q, e);
}
}
Edge e;
int count = 0;
while (count < G.vexNum - 1) {
MinPriorityQueuePop(Q, e);
if (UFSetFind(S, e.u) != UFSetFind(S, e.v)) {
UFSetUnion(S, e.u, e.v);
cout << G.vertices[e.u].data << "---" << G.vertices[e.v].data << " (" << e.weight << ")\n";
count++;
}
}
}
int main() {
// 示例图的初始化
ALGraph G;
G.vexNum = 5;
G.arcNum = 6;
for (int i = 0; i < G.vexNum; ++i) {
G.vertices[i].data = 'A' + i;
G.vertices[i].firstArc = nullptr;
}
// 添加边 (注意:这里需要实现添加边的函数,为简化,直接操作内存)
// A-B 1
ArcNode* edge1 = new ArcNode{1, 1, nullptr};
edge1->next = G.vertices[0].firstArc;
G.vertices[0].firstArc = edge1;
// A-D 3
ArcNode* edge2 = new ArcNode{3, 3, nullptr};
edge2->next = G.vertices[0].firstArc->next;
G.vertices[0].firstArc->next = edge2;
// B-C 4
// ... 类似地添加其他边
// 添加 B-C, C-D, D-E, E-A, A-C 边
// 注意:为了简化,这里没有完整地添加所有边,且直接操作内存可能导致内存泄漏,应使用更安全的内存管理
MST_Kruskal(G);
return 0;
}
//请注意,为了简化代码,这里直接操作内存来添加边,这在实际应用中是不推荐的。应该使用更安全的数据结构或内存管理策略。

1万+

被折叠的 条评论
为什么被折叠?



