MyGraph.h
#ifndef MYGRAPH_H
#define MYGRAPH_H
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#include <iomanip>
#include <math.h>
using namespace std;
template <class T>
struct Edge
{
T adjvex;
double lowcost;
};
struct EdgeNode
{
int adjvex;
EdgeNode* nextedge;
double weight;
};
template <class T>
struct VexNode
{
T data;
EdgeNode* firstedge;
};
template <class T>
class MGraph
{
private:
int vexnum, edgenum;
vector< vector<double> > edges;
vector< VexNode<T> > adjlist;
vector<T> vexs;
void DFS(int v, vector<bool>& vis);
public:
MGraph(T v[], int n, int e);
T GetVexValue(int i);
double GetEdgeValue(int i, int j);
int MiniNum(Edge<T> miniedges[]);
void Print();
void DFSTraverse();
void BFSTraverse();
void Prim(int v);
void Dijkstra(int v, int path[], double dist[]);
};
template <class T>
void MGraph<T>::Prim(int v)
{
Edge<T>* miniedges = new Edge <T>[vexnum];
for (int i = 0; i < vexnum; i++)
{
miniedges[i].adjvex = GetVexValue(v);
miniedges[i].lowcost = GetEdgeValue(v, i);
}
miniedges[v].lowcost = 0;
for (int i = 0; i < vexnum - 1; i++)
{
int k = MiniNum(miniedges);//函数定义
cout << miniedges[k].adjvex << "-->" << GetVexValue(k) << endl;
miniedges[k].lowcost = 0;
for (int j = 0; j < vexnum; j++)
{
if (GetEdgeValue(k, j) < miniedges[j].lowcost)
{
miniedges[j].adjvex = GetVexValue(k);
miniedges[j].lowcost = GetEdgeValue(k, j);
}
}
}
delete[]miniedges;
}
template <class T>
MGraph<T>::MGraph(T v[], int n, int e)
{
vexnum = n;
edgenum = e;
vexs.resize(vexnum);
edges.resize(vexnum);
for (int i = 0; i < n; i++)
vexs[i] = v[i];
for (int i = 0; i < n; i++)
edges[i].resize(vexnum);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (i == j)
edges[i][j] = 0;
else
edges[i][j] = INFINITY;
}
}
int va, vb;
double w;
EdgeNode* p;
adjlist.resize(vexnum);
for (int i = 0; i < vexnum; i++)
{
adjlist[i].data = v[i];
adjlist[i].firstedge = NULL;
}
for (int i = 0; i < e; i++)
{
cout << "输入第" << i + 1 << "条边的起点、终点、权值: ";
cin >> va >> vb >> w;
edges[va][vb] = edges[vb][va] = w;
p = new EdgeNode;
p->adjvex = vb;
p->weight = w;
p->nextedge = adjlist[va].firstedge;
adjlist[va].firstedge = p;
p = new EdgeNode;
p->adjvex = va;
p->weight = w;
p->nextedge = adjlist[vb].firstedge;
adjlist[vb].firstedge = p;
}
cout << "该图的邻接表为:" << endl;
for (int i = 0; i < vexnum; i++)
{
cout << adjlist[i].data << "->";
for (EdgeNode* p = adjlist[i].firstedge; p; p = p->nextedge)
{
cout << p->adjvex << "->";
}
cout << '\n';
}
}
template <class T>
T MGraph<T>::GetVexValue(int i)
{
return vexs[i];
}
template <class T>
double MGraph<T>::GetEdgeValue(int i, int j)
{
return edges[i][j];
}
template <class T>
int MGraph<T>::MiniNum(Edge<T> miniedges[])
{
double min = INFINITY;
int k = -1;
for (int i = 0; i < vexnum; i++)
if (miniedges[i].lowcost != 0 && miniedges[i].lowcost < min)
{
min = miniedges[i].lowcost;
k = i;
}
return k;
}
template <class T>
void MGraph<T>::Print()
{
for (int i = 0; i < vexnum; i++)
{
for (int j = 0; j < vexnum; j++)
{
if (edges[i][j] == INFINITY)
cout << "INFINITY" << " ";
else
cout << setw(8) << edges[i][j] << " ";
}
cout << endl;
}
}
template <class T>
void MGraph<T>::DFSTraverse()
{
vector<bool> visited;
visited.resize(vexnum);
for (int i = 0; i < vexnum; i++)
visited[i] = false;
for (int i = 0; i < vexnum; i++)
{
if (!visited[i])
DFS(i, visited);
}
}
template <class T>
void MGraph<T>::DFS(int v, vector<bool>& visited)
{
cout << vexs[v] << " ";
visited[v] = true;
for (int i = 0; i < vexnum; i++)
{
if (edges[i][v] < 1000 && !visited[i])
{
DFS(i, visited);
}
}
}
template <class T>
void MGraph<T>::BFSTraverse()
{
queue<int> q;
vector<bool> visited;
visited.resize(vexnum);
for (int i = 0; i < vexnum; i++)
{
visited[i] = false;
}
for (int i = 0; i < vexnum; i++)
{
if (!visited[i])
{
cout << i << " ";
visited[i] = true;
q.push(i);
while (!q.empty())
{
int now = q.front();
q.pop();
for (int j = 0; j < vexnum; j++)
{
if (edges[now][j] < 10000 && !visited[j])
{
cout << j << " ";
visited[j] = true;
q.push(j);
}
}
}
}
}
}
template <class T>
void MGraph<T>::Dijkstra(int v, int path[], double dist[])
{
vector<bool> visited;
visited.resize(vexnum);
for (int i = 0; i < vexnum; i++)
{
visited[i] = false;
dist[i] = edges[v][i];
if (dist[i] < INFINITY)
{
path[i] = v;
}
else
{
path[i] = -1;
}
}
dist[v] = 0;
visited[v] = true;
for (int i = 0; i < vexnum; i++)
{
double minn = INFINITY;
int k = 0;
for (int j = 0; j < vexnum; j++)
{
if (!visited[j] && dist[j] < minn)
{
k = j;
minn = dist[j];
}
}
visited[k] = true;
for (int w = 0; w < vexnum; w++)
{
if (!visited[w] && dist[w] > dist[k] + edges[k][w])
{
dist[w] = dist[k] + edges[k][w];
path[w] = k;
}
}
}
}
#endif // MYGRAPH_H
main.cpp
#include "MyGraph.h"
using namespace std;
int main()
{
int n, m, v;
int ed[100], path[100];
double dist[100];
cout << "输入顶点个数: ";
cin >> n;
cout << "输入边的条数: ";
cin >> m;
for (int i = 0; i < n; i++)
{
ed[i] = i;
}
MGraph <int> mgraph(ed, n, m);
cout << "该图的邻接矩阵为: " << endl;
mgraph.Print();
cout << "DFS遍历: ";
mgraph.DFSTraverse();
cout << endl;
cout << "BFS遍历: ";
mgraph.BFSTraverse();
cout << endl << endl;;
while (1)
{
cout << "生成最小生成树" << endl;
cout << "输入源点: ";
cin >> v;
mgraph.Prim(v);
cout << endl;
cout << "最短路径" << endl;
cout << "输入源点: ";
int vv;
cin >> vv;
mgraph.Dijkstra(vv, path, dist);
path[vv] = -1;
for (int i = 0; i < n; i++)
{
cout << "第" << i << "个顶点到源点的最短距离为:" << dist[i] << " 从源点到该点路径为:";
vector<int> temp;
int loc = i;
while (loc != -1)
{
temp.push_back(loc);
loc = path[loc];
}
for (int j = temp.size() - 1; j >= 0; j--)
{
cout << temp[j] << " ";
}
cout << endl;
}
}
return 0;
}