Skip to content

Commit 1b965ab

Browse files
committed
20190428
1 parent 75abe75 commit 1b965ab

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

最小生成树两种算法.cpp

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <queue>
4+
#include <algorithm>
5+
using namespace std;
6+
#define INF 0x3f3f3f3f
7+
#define VertexData int //顶点数据
8+
#define UINT int
9+
#define vexCounts 6 //顶点数量
10+
char vextex[] = { 'A', 'B', 'C', 'D', 'E', 'F' };
11+
struct node
12+
{
13+
VertexData data;
14+
int lowestcost;
15+
}closedge[vexCounts]; //Prim算法中的辅助信息
16+
typedef struct
17+
{
18+
VertexData u;
19+
VertexData v;
20+
int cost; //边的代价
21+
}Arc; //原始图的边信息
22+
void AdjMatrix(int adjMat[][vexCounts]) //邻接矩阵表示法
23+
{
24+
for (int i = 0; i < vexCounts; i++) //初始化邻接矩阵
25+
for (int j = 0; j < vexCounts; j++)
26+
{
27+
adjMat[i][j] = INF;
28+
}
29+
adjMat[0][1] = 6; adjMat[0][2] = 1; adjMat[0][3] = 5;
30+
adjMat[1][0] = 6; adjMat[1][2] = 5; adjMat[1][4] = 3;
31+
adjMat[2][0] = 1; adjMat[2][1] = 5; adjMat[2][3] = 5; adjMat[2][4] = 6; adjMat[2][5] = 4;
32+
adjMat[3][0] = 5; adjMat[3][2] = 5; adjMat[3][5] = 2;
33+
adjMat[4][1] = 3; adjMat[4][2] = 6; adjMat[4][5] = 6;
34+
adjMat[5][2] = 4; adjMat[5][3] = 2; adjMat[5][4] = 6;
35+
}
36+
int Minmum(struct node * closedge) //返回最小代价边
37+
{
38+
int min = INF;
39+
int index = -1;
40+
for (int i = 0; i < vexCounts;i++)
41+
{
42+
if (closedge[i].lowestcost < min && closedge[i].lowestcost !=0)
43+
{
44+
min = closedge[i].lowestcost;
45+
index = i;
46+
}
47+
}
48+
return index;
49+
}
50+
void MiniSpanTree_Prim(int adjMat[][vexCounts], VertexData s)
51+
{
52+
for (int i = 0; i < vexCounts;i++)
53+
{
54+
closedge[i].lowestcost = INF;
55+
}
56+
closedge[s].data = s; //从顶点s开始
57+
closedge[s].lowestcost = 0;
58+
for (int i = 0; i < vexCounts;i++) //初始化辅助数组
59+
{
60+
if (i != s)
61+
{
62+
closedge[i].data = s;
63+
closedge[i].lowestcost = adjMat[s][i];
64+
}
65+
}
66+
for (int e = 1; e <= vexCounts -1; e++) //n-1条边时退出
67+
{
68+
int k = Minmum(closedge); //选择最小代价边
69+
cout << vextex[closedge[k].data] << "--" << vextex[k] << endl;//加入到最小生成树
70+
closedge[k].lowestcost = 0; //代价置为0
71+
for (int i = 0; i < vexCounts;i++) //更新v中顶点最小代价边信息
72+
{
73+
if ( adjMat[k][i] < closedge[i].lowestcost)
74+
{
75+
closedge[i].data = k;
76+
closedge[i].lowestcost = adjMat[k][i];
77+
}
78+
}
79+
}
80+
}
81+
void ReadArc(int adjMat[][vexCounts],vector<Arc> &vertexArc) //保存图的边代价信息
82+
{
83+
Arc * temp = NULL;
84+
for (int i = 0; i < vexCounts;i++)
85+
{
86+
for (int j = 0; j < i; j++)
87+
{
88+
if (adjMat[i][j]!=INF)
89+
{
90+
temp = new Arc;
91+
temp->u = i;
92+
temp->v = j;
93+
temp->cost = adjMat[i][j];
94+
vertexArc.push_back(*temp);
95+
}
96+
}
97+
}
98+
}
99+
bool compare(Arc A, Arc B)
100+
{
101+
return A.cost < B.cost ? true : false;
102+
}
103+
bool FindTree(VertexData u, VertexData v,vector<vector<VertexData> > &Tree)
104+
{
105+
int index_u = INF;
106+
int index_v = INF;
107+
for (int i = 0; i < Tree.size();i++) //检查u,v分别属于哪颗树
108+
{
109+
if (find(Tree[i].begin(), Tree[i].end(), u) != Tree[i].end())
110+
index_u = i;
111+
if (find(Tree[i].begin(), Tree[i].end(), v) != Tree[i].end())
112+
index_v = i;
113+
}
114+
115+
if (index_u != index_v) //u,v不在一颗树上,合并两颗树
116+
{
117+
for (int i = 0; i < Tree[index_v].size();i++)
118+
{
119+
Tree[index_u].push_back(Tree[index_v][i]);
120+
}
121+
Tree[index_v].clear();
122+
return true;
123+
}
124+
return false;
125+
}
126+
void MiniSpanTree_Kruskal(int adjMat[][vexCounts])
127+
{
128+
vector<Arc> vertexArc;
129+
ReadArc(adjMat, vertexArc);//读取边信息
130+
sort(vertexArc.begin(), vertexArc.end(), compare);//边按从小到大排序
131+
vector<vector<VertexData> > Tree(vexCounts); //6棵独立树
132+
for (int i = 0; i < vexCounts; i++)
133+
{
134+
Tree[i].push_back(i); //初始化6棵独立树的信息
135+
}
136+
for (int i = 0; i < vertexArc.size(); i++)//依次从小到大取最小代价边
137+
{
138+
VertexData u = vertexArc[i].u;
139+
VertexData v = vertexArc[i].v;
140+
if (FindTree(u, v, Tree))//检查此边的两个顶点是否在一颗树内
141+
{
142+
cout << vextex[u] << "---" << vextex[v] << endl;//把此边加入到最小生成树中
143+
}
144+
}
145+
}
146+
147+
int main()
148+
{
149+
int adjMat[vexCounts][vexCounts] = { 0 };
150+
AdjMatrix(adjMat); //邻接矩阵
151+
cout << "Prim :" << endl;
152+
MiniSpanTree_Prim(adjMat,0); //Prim算法,从顶点0开始.
153+
cout << "-------------" << endl << "Kruskal:" << endl;
154+
MiniSpanTree_Kruskal(adjMat);//Kruskal算法
155+
system("pause");
156+
return 0;
157+
}

0 commit comments

Comments
 (0)