- 相应的算法是基于邻接矩阵实现的
#include <iostream>
#include <numeric>
#include <queue>
#include <vector>
using namespace std;
const int VEX_MAX = 100;
bool visited[VEX_MAX];
int Vset[VEX_MAX];//判断是否有回路
typedef struct Node{
char* data;
int vexnum, arcnum;
int **G;
}*MGraph;
//边
typedef struct Edge{
int head;
int tail;
int lowcost;
}*Edges;
//创建邻接矩阵
MGraph creatGraph()
{
MGraph graph = new Node;
int vex, arc;
cout << "请输入顶点个数和边数:" << endl;
cin >> vex >> arc;
graph->vexnum = vex;
graph->arcnum = arc;
graph->data = new char[vex];
cout << "请输入顶点数据:" << endl;
char data;
for (int i = 0; i < vex; i++)
{
cin >> data;
graph->data[i] = data;
}
cout << "请输入边的起始点及其权重:" << endl;
graph->G = new int*[vex];
for (int i = 0; i < vex; i++)
graph->G[i] = new int[vex];
for (int i = 0; i < graph->vexnum; i++)
{
for (int j = 0; j < graph->vexnum; j++)
{
graph->G[i][j] = 0;
}
}
int start, end, weight;
for (int i = 0; i < arc; i++)
{
cin >> start;
cin >> end;
cin >> weight;
graph->G[start - 1][end - 1] = weight;
graph->G[end - 1][start - 1] = weight;
}
return graph;
}
void DFS(MGraph graph, int v)
{
visited[v] = true;
cout << graph->data[v] << "->";
for (int i = 0; i < graph->vexnum; i++)
{
if (graph->G[v][i] != 0 && !visited[i])
{
DFS(graph, i);
}
}
}
//DFS算法
void DFSTraverse(MGraph graph)
{
for (int i = 0; i < graph->vexnum; i++)
visited[i] = false;
for (int i = 0; i < graph->vexnum; i++)
{
if (!visited[i])
DFS(graph, i);
}
}
//BFS算法
void BFSTraverse(MGraph graph)
{
queue<int> MyQueue;
for (int i = 0; i < graph->vexnum; i++)
visited[i] = false;
for (int i = 0; i < graph->vexnum; i++)
{
if (!visited[i])
{
visited[i] = true;
cout << graph->data[i] << "->";
MyQueue.push(i);
while (!MyQueue.empty())
{
int v = MyQueue.front();
MyQueue.pop();
for (int i = 0; i < graph->vexnum; i++)
{
if (graph->G[v][i] != 0 && !visited[i])
{
visited[i] = true;
cout << graph->data[i] << "->";
MyQueue.push(i);
}
}
}
}
}
}
//根据起始点返回位置
int LocateVex(MGraph graph, char data)
{
for (int i = 0; i < graph->vexnum; i++)
{
if (data == graph->data[i])
return i;
}
return -1;
}
//普利姆算法
void PrimAlgorithm(MGraph graph,char data)
{
int v = LocateVex(graph, data);
for (int i = 0; i < graph->vexnum; i++)
visited[i] = false;
visited[v] = true;
//h1和h2记录两个顶点的下标
int h1, h2;
int minWeight = 10000;
for (int k = 1; k < graph->vexnum; k++)//总共边数
{
//遍历整个图
for (int i = 0; i < graph->vexnum; i++)
{
for (int j = 0; j < graph->vexnum; j++)
{
if (visited[i] && !visited[j] && graph->G[i][j] < minWeight && graph->G[i][j]!=0 )
{
minWeight = graph->G[i][j];//找到整个图中前面一个顶点被访问后面一个顶点没有被访问且权值最小的
h1 = i;
h2 = j;
}
}
}
cout << "从顶点" << graph->data[h1] << "到" << graph->data[h2] << "权值为:" << graph->G[h1][h2] << endl;
minWeight = 10000;
visited[h2] = true;
}
}
//对边进行排序 冒泡排序
void sortEdges(MGraph graph, Edges& edges)
{
for (int i = 0; i < graph->arcnum - 1; i++)
{
for (int j = 0; j < graph->arcnum - 1 - i; j++)
{
if (edges[j].lowcost > edges[j + 1].lowcost)
{
Edge temp = edges[j];
edges[j] = edges[j + 1];
edges[j + 1] = temp;
}
}
}
}
int getEnd(int* vexs, int i)
{
while (vexs[i] != 0)
i = vexs[i];
return i;
}
//克鲁斯卡尔算法
void KruskalAlgorithm(MGraph graph, Edges edges)
{
int v1, v2;
int vs1, vs2;
int count = 0;
sortEdges(graph, edges);
for (int i = 0; i < graph->vexnum; i++)
Vset[i] = i;
for (int i = 0; i < graph->arcnum; i++)
{
v1 = edges[i].head;
v2 = edges[i].tail;
//vs1 = getEnd(Vset, v1);//判断是否有回路 如果边的两个顶点都指向同一个终点 则有回路
//vs2 = getEnd(Vset, v2);
vs1 = Vset[v1];
vs2 = Vset[v2];
if (vs1 != vs2)
{
cout << "从顶点" << graph->data[v1] << "到" << graph->data[v2] << "权值为:" << edges[i].lowcost << endl;
count++;
if (count == graph->vexnum - 1)
break;
//Vset[vs1] = vs2;//边连接之后 更新终点
for (int j = 0; j < graph->vexnum; j++)
{
if (Vset[j] == vs2)
Vset[j] = vs1;//统一编号
}
}
}
}
//提取边
Edges createEdges(MGraph graph)
{
Edges edges = new Edge[graph->arcnum];
int count = 0;
for (int i = 0; i < graph->vexnum; i++)
{
for (int j = i; j < graph->vexnum; j++)
{
if (graph->G[i][j] != 0)
{
edges[count].head = i;
edges[count].tail = j;
edges[count].lowcost = graph->G[i][j];
count++;
}
}
}
return edges;
}
//打印边
void printEdges(MGraph graph, Edges edges)
{
for (int i = 0; i < graph->arcnum; i++)
{
cout << edges[i].head << "->" << edges[i].tail << "=" << edges[i].lowcost << endl;
}
}
//打印图
void printGraph(MGraph graph)
{
cout << "邻接矩阵为:" << endl;
for (int i = 0; i < graph->vexnum; i++)
{
for (int j = 0; j < graph->vexnum; j++)
{
cout << graph->G[i][j] << " ";
}
cout << endl;
}
}
int main()
{
MGraph graph = creatGraph();
Edges edges = createEdges(graph);
cout << "普利姆算法生成最小生成树:" << endl;
PrimAlgorithm(graph, 'A');
cout << "-----" << endl;
cout << "克鲁斯卡尔算法生成最小生成树:" << endl;
KruskalAlgorithm(graph, edges);
printGraph(graph);
cout << "**********************" << endl;
cout << "深度优先遍历:";
DFSTraverse(graph);
cout << endl;
cout << "广度优先遍历:";
BFSTraverse(graph);
cout << endl;
return 0;
}
测试用例
6 10
A B C D E F
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6