作为一个计算机专业的上二年级学生,学了一年之后居然写数据结构的作业如此头疼,学艺不精啊……在这里把这个程序贴出来,求各位指教……
习惯不好,没什么注释……
题目是输入一个无向图(无向网)的邻接矩阵之后应用Prim,Kruskal,破圈法,去边法四种方法中的三种求最小代价生成树,由于原来编过一个图的类,然后就把输入的邻接矩阵改成输入的边了,输出时用0-1矩阵表示的无向图来表示最小代价生成树。
这是定义的类:
#define INFINITY INT_MAX
//定义表示图的类型的字符常量.DG = 1为有向图,DN = 2为友向网,UDG = 3为无向图,UDN = 4为无向网.
enum {DG = 1, DN, UDG, UDN};
//定义图类graph
class graph
{
public:
graph(int Gkind = 0)
{
Kind = Gkind;
switch (Gkind)
{
case DG: createDG(); break;
case DN: createDN(); break;
case UDG: createUDG(); break;
case UDN: createUDN(); break;
default:
ArcNum = VerNum = 0;
AdjMatrix = NULL;
break;
}
}
graph(graph &g)
{
Kind = g.Kind;
VerNum = g.VerNum;
ArcNum = g.ArcNum;
AdjMatrix = new int* [VerNum];
for (int i = 0; i <= VerNum - 1; ++i)
{
AdjMatrix[i] = new int [VerNum];
}
for (int a = 0; a <= VerNum - 1; ++a)
{
for (int b = 0; b <= VerNum - 1; ++b)
{
AdjMatrix[a][b] = g.AdjMatrix[a][b];
}
}
}
~graph()
{
for (int a = 0; a <= VerNum - 1; ++a)
{
delete [] AdjMatrix[a];
AdjMatrix[a] = NULL;
}
delete [] AdjMatrix;
AdjMatrix = NULL;
}
int applyMemo (int ver)
{
AdjMatrix = new int* [ver];
for (int a = 0; a <= ver - 1; ++a)
{
AdjMatrix[a] = new int [ver];
}
return 1;
}
void createDG (void)
{
cout << "====== Create a directed graph ======" << endl;
cout << "Please input the number of vertices(greater than 0):" << endl;
int ver;
cin >> ver;
VerNum = ver;
applyMemo(ver);
cout << "Please input the number of the arcs(not less than 0):" << endl;
int arc;
cin >> arc;
ArcNum = arc;
for (int a = 0; a <= ver - 1; ++a)
{
for (int b = 0; b <= ver - 1; ++b)
{
AdjMatrix[a][b] = 0;
}
}
int v1;
int v2;
int out;
for (int i = 1; i <= arc; ++i)
{
cout << "Please input the number of the two vertices and out degree/n"
<< "(If v1 to v2, input as v1[Space]v2[Space]outdegree[Enter]):" << endl;
cin >> v1 >> v2 >> out;
AdjMatrix[v1][v2] = out;
}
cout << "Creating a directed graph completed." << endl;
}
void createDN (void)
{
cout << "====== Create a directed net ======" << endl;
cout << "Please input the number of vertices(greater than 0):" << endl;
int ver;
cin >> ver;
VerNum = ver;
applyMemo(ver);
cout << "Please input the number of the arcs(not less than 0):" << endl;
int arc;
cin >> arc;
ArcNum = arc;
for (int a = 0; a <= ver - 1; ++a)
{
for (int b = 0; b <= ver - 1; ++b)
{
AdjMatrix[a][b] = INFINITY;
}
}
int v1;
int v2;
int weight;
for (int i = 1; i <= arc; ++i)
{
cout << "Please input the number of the two vertices and weight/n"
<< "(If v1 to v2, input as v1[Space]v2[Space]Weight[Enter]):" << endl;
cin >> v1 >> v2 >> weight;
AdjMatrix[v1][v2] = weight;
}
cout << "Creating a directed net completed." << endl;
}
void createUDG (void)
{
cout << "====== Create an undirected graph ======" << endl;
cout << "Please input the number of vertices(greater than 0):" << endl;
int ver;
cin >> ver;
VerNum = ver;
applyMemo(ver);
cout << "Please input the number of the arcs(not less than 0):" << endl;
int arc;
cin >> arc;
ArcNum = arc;
for (int a = 0; a <= ver - 1; ++a)
{
for (int b = 0; b <= ver - 1; ++b)
{
AdjMatrix[a][b] = 0;
}
}
int v1;
int v2;
int out;
for (int i = 1; i <= arc; ++i)
{
cout << "Please input the number of the two vertices and out degree/n"
<< "(If v1 to v2, input as v1[Space]v2[Space]outdegree[Enter]):" << endl;
cin >> v1 >> v2 >> out;
AdjMatrix[v1][v2] = AdjMatrix[v2][v1] = out;
}
cout << "Creating an undirected graph completed." << endl;
}
void createUDN (void)
{
cout << "====== Create an undirected net ======" << endl;
cout << "Please input the number of vertices(greater than 0):" << endl;
int ver;
cin >> ver;
VerNum = ver;
applyMemo(ver);
cout << "Please input the number of the arcs(not less than 0):" << endl;
int arc;
cin >> arc;
ArcNum = arc;
for (int a = 0; a <= ver - 1; ++a)
{
for (int b = 0; b <= ver - 1; ++b)
{
AdjMatrix[a][b] = INFINITY;
}
}
int v1;
int v2;
int weight;
for (int i = 1; i <= arc; ++i)
{
cout << "Please input the number of the two vertices and weight/n"
<< "(If v1 to v2, input as v1[Space]v2[Space]Weight[Enter]):" << endl;
cin >> v1 >> v2 >> weight;
AdjMatrix[v1][v2] = AdjMatrix[v2][v1] = weight;
}
cout << "Creating an undirected net completed." << endl;
}
void modify (int v1, int v2, int info)
{
if (0 <= v1&&v1 <= VerNum - 1&&0 <= v2&&v2 <= VerNum - 1)
{
if (Kind == DG||Kind == DN)
{
AdjMatrix[v1][v2] = info;
}
else
{
AdjMatrix[v1][v2] = AdjMatrix[v2][v1] = info;
}
}
else
{
cerr << "ERROR" << endl;
}
}
void find (int v1, int v2)
{
if (0 <= v1&&v1 <= VerNum - 1&&0 <= v2&&v2 <= VerNum - 1)
{
cout << "Vertex 1: " << v1 << " Vertex 2: " << v2 << " Arc: " << AdjMatrix[v1][v2] << endl;;
}
else
{
cerr << "ERROR" << endl;
}
}
int getInfo (int v1, int v2)
{
if (0 <= v1&&v1 <= VerNum - 1&&0 <= v2&&v2 <= VerNum - 1)
{
return AdjMatrix[v1][v2];
}
else
{
cerr << "ERROR" << endl;
return -1;
}
}
int FirstAdjVex (int v)
{
int first = 0;
if (0 <= v&&v <= VerNum - 1)
{
if (Kind == DG||Kind == UDG)
{
for (; first <= VerNum - 1&&AdjMatrix[v][first] == 0; ++first)
;
}
else if (Kind == DN||Kind == UDN)
{
for (; first <= VerNum - 1&&AdjMatrix[v][first] == INFINITY; ++first)
;
}
if (first < VerNum)
{
return first;
}
else
{
return -1;
}
}
else
{
cerr << "ERROR" << endl;
return -1;
}
}
int NextAdjVex (int i, int j)
{
int next = j + 1;
if (0 <= i&&i <= VerNum - 1&&0 <= j&&j <= VerNum - 1)
{
if (Kind == DG||Kind == UDG)
{
for (; next <= VerNum - 1&&AdjMatrix[i][next] == 0; ++next)
;
}
else if (Kind == DN||Kind == UDN)
{
for (; next <= VerNum - 1&&AdjMatrix[i][next] == INFINITY; ++next)
;
}
if (next < VerNum)
{
return next;
}
else
{
return -1;
}
}
else
{
cerr << "ERROR" << endl;
return -1;
}
}
void out (void)
{
cout << "The adjacency matrix of the ";
switch (Kind)
{
case DG: cout << "directed graph"; break;
case UDG: cout << "undirected graph"; break;
case DN: cout << "directed net"; break;
case UDN: cout << "undirected net"; break;
default: break;
}
cout << " is:" << endl;
for (int a = 0; a <= VerNum - 1; ++a)
{
for (int b = 0; b <= VerNum - 1; ++b)
{
if (AdjMatrix[a][b] == INFINITY)
{
cout << "~ ";
}
else
{
cout << AdjMatrix[a][b] << ' ';
}
}
cout << endl;
}
}
int getVerNum (void)
{
return VerNum;
}
int getArcNum (void)
{
return ArcNum;
}
int **getAdjMatrix (void)
{
return AdjMatrix;
}
private:
int Kind;
int ArcNum;
int VerNum;
int **AdjMatrix;
};
这是程序的其他部分:
#include <iostream>
#include <cstdlib>
using namespace std;
#include "graph.h"
void MST_PRIM (graph g)
{
int ver = g.getVerNum();
int *X = new int [ver];
for (int i = 0; i <= ver - 1; ++i)
{
X[i] = 0;
}
X[0] = 1;
int **mst = new int* [ver];
for (int i = 0; i <= ver - 1; ++i)
{
mst[i] = new int [ver];
}
for (int a = 0; a <= ver - 1; ++a)
{
for (int b = 0; b <= ver - 1; ++b)
{
mst[a][b] = 0;
}
}
int minLen;
int min_v1;
int min_v2;
for (int counter = 1; counter <= ver - 1; ++counter)
{
minLen = INFINITY;
for (int v1 = 0; v1 <= ver - 1; ++v1)
{
if (X[v1] == 1)
{
for (int v2 = 0; v2 <= ver - 1; ++v2)
{
if (X[v2] == 0&&g.getInfo(v1, v2) < minLen)
{
minLen = g.getInfo(v1, v2);
min_v1 = v1;
min_v2 = v2;
}
}
}
}
X[min_v2] = 1;
mst[min_v1][min_v2] = mst[min_v2][min_v1] = 1;
}
cout << "The minimum spanning tree is(Using Prim's algorithm):" << endl;
for (int c = 0; c <= ver - 1; ++c)
{
for (int d = 0; d <= ver - 1; ++d)
{
cout << mst[c][d] << ' ';
}
cout << endl;
}
delete [] X;
X = NULL;
for (int e = 0; e <= ver - 1; ++e)
{
delete [] mst[e];
mst[e] = NULL;
}
delete [] mst;
mst = NULL;
}
class edge
{
public:
int v1;
int v2;
int weight;
};
void MST_KRUSKAL (graph g)
{
int findLoop (int **mst, int num);
void sort (edge *&Edge, int num);
int arc = g.getArcNum();
edge *Edge = new edge [arc];
for (int a = 0; a <= arc - 1; ++a)
{
Edge[a].v1 = Edge[a].v2 = Edge[a].weight = 0;
}
int ver = g.getVerNum();
int counter = 0;
int info;
for (int b = 0; counter <= arc - 1&&b <= ver - 1; ++b)
{
for (int c = 0; counter <= arc - 1&&c <= ver - 1; ++c)
{
info = g.getInfo(b, c);
if (0 < info&&INFINITY > info&&c > b)
{
Edge[counter].v1 = b;
Edge[counter].v2 = c;
Edge[counter].weight = info;
++counter;
}
}
}
sort(Edge, arc);
int added = 0;
int **mst = new int* [ver];
for (int d = 0; d <= ver - 1; ++d)
{
mst[d] = new int [ver];
}
for (int e = 0; e <= ver - 1; ++e)
{
for (int f = 0; f <= ver - 1; ++f)
{
mst[e][f] = 0;
}
}
for (int h = 0; added <= ver - 1&&h <= arc - 1; ++h)
{
int v = Edge[h].v1;
int v1 = Edge[h].v1;
int v2 = Edge[h].v2;
mst[v1][v2] = mst[v2][v1] = 1;
if (findLoop(mst, ver) == 0)
{
++added;
}
else
{
mst[v1][v2] = mst[v2][v1] = 0;
}
}
cout << "The minimum spanning tree is(Using Kruskal's algorithm):" << endl;
for (int i = 0; i <= ver - 1; ++i)
{
for (int j = 0; j <= ver - 1; ++j)
{
cout << mst[i][j] << ' ';
}
cout << endl;
}
delete [] Edge;
Edge = NULL;
for (int k = 0; k <= ver - 1; ++k)
{
delete [] mst[k];
mst[k] = NULL;
}
delete [] mst;
mst = NULL;
}
void sort (edge *&Edge, int num)
{
edge tmp;
for (int pass = 1; pass <= num - 1; ++pass)
{
for (int i = 0; i <= num - pass - 1; ++i)
{
if (Edge[i].weight > Edge[i + 1].weight)
{
tmp = Edge[i + 1];
Edge[i + 1] = Edge[i];
Edge[i] = tmp;
}
}
}
}
int findLoop (int **mst, int num)
{
void f (int **mst, int num, int cur_ver, int *visited, int &flag);
int flag = 0;
int *visited = new int [num];
for (int i = 0; i <= num - 1; ++i)
{
visited[i] = 0;
}
f(mst, num, 0, visited, flag);
delete [] visited;
visited = NULL;
return flag;
}
void f (int **mst, int num, int cur_ver, int *visited, int &flag)
{
visited[cur_ver] = 1;
int counter = 0;
for (int i = 0; i <= num - 1; ++i)
{
if (mst[cur_ver][i] == 1&&visited[i])
{
++counter;
}
}
if (counter >= 2)
{
flag = 1;
}
if (flag == 0)
{
for (int j = 0; j <= num - 1; ++j)
{
if (mst[cur_ver][j] == 1&&!visited[j])
{
f(mst, num, j, visited, flag);
}
}
}
visited[cur_ver] = 0;
}
void MST_DL (graph g)
{
int findMax (graph g, edge &max);
graph g_copy(g);
edge blank = {0, 0, 0};
edge max;
int ver = g_copy.getVerNum();
int **mst = new int* [ver];
for (int a = 0; a <= ver - 1; ++a)
{
mst[a] = new int [ver];
}
for (int b = 0; b <= ver - 1; ++b)
{
for (int c = 0; c <= ver - 1; ++c)
{
mst[b][c] = 0;
}
}
int info;
for (int d = 0; d <= ver - 1; ++d)
{
for (int e = 0; e <= ver - 1; ++e)
{
info = g_copy.getInfo(d, e);
if (info > 0&&info < INFINITY)
{
mst[d][e] = 1;
}
}
}
max = blank;
while (findMax(g_copy, max))
{
g_copy.modify(max.v1, max.v2, INFINITY);
g_copy.modify(max.v2, max.v1, INFINITY);
mst[max.v1][max.v2] = mst[max.v2][max.v1] = 0;
max = blank;
}
cout << "The minimum spanning tree is(Using destroy loop algorithm):" << endl;
for (int i = 0; i <= ver - 1; ++i)
{
for (int j = 0; j <= ver - 1; ++j)
{
cout << mst[i][j] << ' ';
}
cout << endl;
}
for (int k = 0; k <= ver - 1; ++k)
{
delete [] mst[k];
mst[k] = NULL;
}
delete [] mst;
mst = NULL;
}
int findMax (graph g, edge &max)
{;
void findLoopMaxEdge (graph g, int cur_ver, int num, int visited[], edge loop[], int &flag, int pos, edge &max);
int num = g.getVerNum();
int flag = 0;
int *visited = new int [num];
edge *loop = new edge [num];
for (int a = 0; a <= num - 1; ++a)
{
loop[a].v1 = loop[a].v2 = loop[a].weight = 0;
}
for (int i = 0; i <= num - 1; ++i)
{
visited[i] = 0;
}
findLoopMaxEdge(g, 0, num, visited, loop, flag, 0, max);
delete [] visited;
visited = NULL;
delete [] loop;
loop = NULL;
return flag;
}
void findLoopMaxEdge (graph g, int cur_ver, int num, int visited[], edge loop[], int &flag, int pos, edge &max)
{
if (visited[cur_ver] == 1)
{
flag = 1;
int start = 0;
for (; loop[start].v1 != cur_ver&&start <= pos - 1; ++start)
;
for (int i = start; i <= pos - 1; ++i)
{
if (max.weight < loop[i].weight)
{
max = loop[i];
}
}
}
if (flag == 0)
{
visited[cur_ver] = 1;
for (int a = 0; flag == 0&&a <= num - 1; ++a)
{
int info = g.getInfo(cur_ver, a);
if (info > 0&&info < INFINITY)
{
loop[pos].v1 = cur_ver;
loop[pos].v2 = a;
loop[pos].weight = info;
g.modify(a, cur_ver, INFINITY);
findLoopMaxEdge(g, a, num, visited, loop, flag, pos + 1, max);
g.modify(a, cur_ver, info);
}
}
visited[cur_ver] = 0;
}
}
void MST_DE (graph g)
{
int connect (int **mst, int num);
void sort (edge *&Edge, int num);
int arc = g.getArcNum();
edge *Edge = new edge [arc];
for (int a = 0; a <= arc - 1; ++a)
{
Edge[a].v1 = Edge[a].v2 = Edge[a].weight = 0;
}
int ver = g.getVerNum();
int counter = 0;
int info;
for (int b = 0; counter <= arc - 1&&b <= ver - 1; ++b)
{
for (int c = 0; counter <= arc - 1&&c <= ver - 1; ++c)
{
info = g.getInfo(b, c);
if (0 < info&&INFINITY > info&&c > b)
{
Edge[counter].v1 = b;
Edge[counter].v2 = c;
Edge[counter].weight = info;
++counter;
}
}
}
sort(Edge, arc);
int **mst = new int* [ver];
for (int d = 0; d <= ver - 1; ++d)
{
mst[d] = new int [ver];
}
for (int e = 0; e <= ver - 1; ++e)
{
for (int f = 0; f <= ver - 1; ++f)
{
info = g.getInfo(e, f);
if (info > 0&&info < INFINITY)
{
mst[e][f] = 1;
}
else
{
mst[e][f] = 0;
}
}
}
int remain = arc;
for (int h = arc - 1; remain >= ver; --h)
{
int v1 = Edge[h].v1;
int v2 = Edge[h].v2;
mst[v1][v2] = mst[v2][v1] = 0;
if (connect(mst, ver) == 1)
{
--remain;
}
else
{
mst[v1][v2] = mst[v2][v1] = 1;
}
}
cout << "The minimum spanning tree is(Using delete edge algorithm):" << endl;
for (int i = 0; i <= ver - 1; ++i)
{
for (int j = 0; j <= ver - 1; ++j)
{
cout << mst[i][j] << ' ';
}
cout << endl;
}
delete [] Edge;
Edge = NULL;
for (int k = 0; k <= ver - 1; ++k)
{
delete [] mst[k];
mst[k] = NULL;
}
delete [] mst;
mst = NULL;
}
int connect (int **mst, int num)
{
void c (int **mst, int num, int *visited, int cur_ver);
int *visited = new int [num];
for (int a = 0; a <= num - 1; ++a)
{
visited[a] = 0;
}
c(mst, num, visited, 0);
for (int b = 0; b <= num - 1; ++b)
{
if (visited[b] == 0)
{
return 0;
}
}
return 1;
}
void c (int **mst, int num, int *visited, int cur_ver)
{
visited[cur_ver] = 1;
for (int a = 0; a <= num - 1; ++a)
{
if (mst[cur_ver][a] == 1&&visited[a] == 0)
{
c (mst, num, visited, a);
}
}
}
int main ()
{
graph g(UDN);
g.out();
MST_PRIM(g);
MST_KRUSKAL(g);
MST_DL(g);//破圈法
MST_DE(g);//去边法
system("PAUSE");
return 0;
}