一、思路:
总共选择n- 1条边,所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中。
意思就是:n个顶点,要取n-1条边,形成连通分量。每一次取权值最小的一条边,如果不形成回路就添加到最小生成树中;否则,舍弃这条边,取权值次小的边,重复前面步骤,直到取了n-1条边和所有顶结点被访问过。
最小生成树:minimum-cost spanning tree (MST)
二、实现程序:
1.Graph.h:我就直接把之间写过的图程序拿过来
#ifndef Graph_h
#define Graph_h
#include <iostream>
using namespace std;
const int DefaultVertices = 30;
template <class T, class E>
struct Edge { // 边结点的定义
int dest; // 边的另一顶点位置
E cost; // 表上的权值
Edge<T, E> *link; // 下一条边链指针
};
template <class T, class E>
struct Vertex { // 顶点的定义
T data; // 顶点的名字
Edge<T, E> *adj; // 边链表的头指针
};
template <class T, class E>
class Graphlnk {
public:
const E maxWeight = 100000; // 代表无穷大的值(=∞)
Graphlnk(int sz=DefaultVertices); // 构造函数
~Graphlnk(); // 析构函数
void inputGraph(); // 建立邻接表表示的图
void outputGraph(); // 输出图中的所有顶点和边信息
T getValue(int i); // 取位置为i的顶点中的值
E getWeight(int v1, int v2); // 返回边(v1, v2)上的权值
bool insertVertex(const T& vertex); // 插入顶点
bool insertEdge(int v1, int v2, E weight); // 插入边
bool removeVertex(int v); // 删除顶点
bool removeEdge(int v1, int v2); // 删除边
int getFirstNeighbor(int v); // 取顶点v的第一个邻接顶点
int getNextNeighbor(int v,int w); // 取顶点v的邻接顶点w的下一邻接顶点
int getVertexPos(const T vertex); // 给出顶点vertex在图中的位置
int numberOfVertices(); // 当前顶点数
private:
int maxVertices; // 图中最大的顶点数
int numEdges; // 当前边数
int numVertices; // 当前顶点数
Vertex<T, E> * nodeTable; // 顶点表(各边链表的头结点)
};
// 构造函数:建立一个空的邻接表
template <class T, class E>
Graphlnk<T, E>::Graphlnk(int sz) {
maxVertices = sz;
numVertices = 0;
numEdges = 0;
nodeTable = new Vertex<T, E>[maxVertices]; // 创建顶点表数组
if(nodeTable == NULL) {
cerr << "存储空间分配错误!" << endl;
exit(1);
}
for(int i = 0; i < maxVertices; i++)
nodeTable[i].adj = NULL;
}
// 析构函数
template <class T, class E>
Graphlnk<T, E>::~Graphlnk() {
// 删除各边链表中的结点
for(int i = 0; i < numVertices; i++) {
Edge<T, E> *p = nodeTable[i].adj; // 找到其对应链表的首结点
while(p != NULL) { // 不断地删除第一个结点
nodeTable[i].adj = p->link;
delete p;
p = nodeTable[i].adj;
}
}
delete []nodeTable; // 删除顶点表数组
}
// 建立邻接表表示的图
template <class T, class E>
void Graphlnk<T, E>::inputGraph() {
int n, m; // 存储顶点树和边数
int i, j, k;
T e1, e2; // 顶点
E weight; // 边的权值
cout << "请输入顶点数和边数:" << endl;
cin >> n >> m;
cout << "请输入各顶点:" << endl;
for(i = 0; i < n; i++) {
cin >>