以下代码未经验证:
#include<vector> #include<algorithm> using namespace std; #define MAXINT 0xffff #define vertexNum 10 typedef struct Graph { int border[vertexNum][vertexNum]; }Graph; typedef struct border { int v1; //第一个顶点 int v2; //第二个顶点 int weight; //权重 }BORDER; //边结构 Graph G; bool cmp(BORDER a, BORDER b) //作为排序回调函数,按权重对结构体从小到大排序 { return a.weight < b.weight; } vector<BORDER> minTree; void Kruskal() { vector<BORDER> b; BORDER temp; for(int i = 0; i < vertexNum - 1; i++) //列出所有边并存储进边结构 { for(int j = i + 1; j < vertexNum; j++) { if(G.border[i][j] < MAXINT) { temp = { i, j, G.border[i][j] }; b.push_back(temp); } } } sort(b.begin(), b.end(), cmp); //对所有边按权重由小到大排序 int bSet[vertexNum] = { 0 }; //初始时每个顶点都为独立的树,对应集合不同 for(int i = 0; i < vertexNum; i++) { bSet[i] = i; //bSet[]所有i对应的值不相同,索性就都等于i,下标肯定不同,所以值不同。后续把i1,i2值设为相同的话,则意味着,i1,i2在同一个集合(树) } int size = b.size; for(int i = 0; i < size; i++) { if(bSet[b[i].v1] != bSet[b[i].v2]) //如果该边的两个顶点不在同一个集合(树) { minTree.push_back(b[i]); //把该边存到结果集 for(int j = 0; j < vertexNum; j++) { if(bSet[j] == bSet[b[i].v1]) //找出b[i].v1所在集合的所有点 { bSet[j] = bSet[b[i].v2]; //把b[i].v1这个点所在集合的所有的点都放到bSet[i].v2所在集合,其实就是合并这个两个点所在集合 } } } } }
prim算法代码如下,未经验证:
vector<BORDER> borders; void prim() { bool isVisited[vertexNum] = {0}; int curVertex = 0, curNextVertex = 0; isVisited[curVertex] = true; int minBorder = MAXINT; BORDER temp; int vistedBCount = 0; while( vistedBCount < vertexNum - 1) { for (int i = 1; i < vertexNum; i++) { if (curVertex != i && G.border[curVertex][i] < minBorder && isVisited[i] == false) { minBorder = G.border[curVertex][i]; curNextVertex = i; } } temp.v1 = curVertex; temp.v2 = curNextVertex; temp.weight = minBorder; borders.push_back(temp); curVertex = curNextVertex; vistedBCount++; } }