图的实现:使用邻接矩阵
使用方法:
创建类实例:
template <typename IndexType,typename DataType>
class Graph{
public:
Graph() {}//构造函数
Graph(const Graph&);//复制构造函数
Graph& operator=(const Graph&);//赋值函数
Graph(Graph&&);//移动构造函数
Graph& operator=(Graph&&);//移动赋值函数
void show();//显示图
bool insert(IndexType, DataType, IndexType, bool = false);//插入
bool del(IndexType, IndexType, bool = false);//删除
bool update(IndexType, DataType, IndexType, bool = false);//更新
void clear() { name2dex.clear(); dex2name.clear(); mat.clear(); }//清空
DataType shortestpath(IndexType,IndexType);//求最短路径
std::pair<bool, std::vector<IndexType>> topologicalsort();//求拓扑排序
~Graph() {}
};
//例:
Graph<std::string,int> g;
功能:
1.插入边
bool insert(IndexType, DataType, IndexType, bool = false);//插入成功返回true
//当最后一个参数为true时,即插入无向边
//例如:g.insert("A",1,"B");
//这就插入了一条从A到B的边,边权值为1
2.删除边
bool del(IndexType, IndexType, bool = false);//删除成功返回true
//当最后一个参数为true时,删除无向边
//例如:g.del("A","B");
//这就删除了从A到B的边
3.更新边权值
bool update(IndexType, DataType, IndexType, bool = false);
//与insert方法一致
4.清空图
void clear();
5.求最短路径(Dijkstra)
DataType shortestpath(IndexType,IndexType);//返回某点到某点间的最短路径长度
6.求拓扑排序
std::pair<bool, std::vector<IndexType>> topologicalsort();
//返回pair类型
//其中pair.first=true时则有拓扑排序
//pair.second为拓扑排序结果
一个例子:
主函数实现:
#include <iostream>
#include "Graph_m.h"
#define A "A"
#define B "B"
#define C "C"
#define D "D"
#define E "E"
#define F "F"
using namespace std;
template<typename DataType>
void show(vector<DataType> arr) {//显示vector
for (DataType i : arr)cout << i << " "; cout << endl;
}
int main()
{
using IndexType=string;
Graph<IndexType, int> G1;
G1.insert(A, 1, B);
G1.insert(A, 3, C);
G1.insert(A, 10, F);
G1.insert(B, 4, E);
G1.insert(C, 1, D);
G1.insert(E, 2, F);
G1.insert(D, 1, F);
G1.show();cout<<endl;
show(G1.topologicalsort().second);//显示拓扑排序
cout << G1.shortestpath(A, F);//显示最短距离
}
结果:
Graph类模板完整代码:
#ifndef _GRAPH_M_
#define _GRAPH_M_
#include<iostream>
#include<vector>
#include<map>
#include<unordered_map>
#include<queue>
template <typename IndexType,typename DataType>
class Graph {
std::unordered_map<IndexType, int> name2dex;//index start from 1
std::unordered_map<int, IndexType> dex2name;//index start from 1
std::vector<std::vector<DataType>> mat;
struct nodedist {
int index;
DataType dist;
nodedist(int i, DataType d) :index(i), dist(d) {}
bool operator<(const nodedist& other)const { return dist > other.dist; }
};
public:
Graph() {}
Graph(std::vector<IndexType>&, std::vector<std::vector<DataType>>&);
Graph(const Graph&);
Graph& operator=(const Graph&);
Graph(Graph&&);
Graph& operator=(Graph&&);
void show();
bool insert(IndexType, DataType, IndexType, bool = false);
bool del(IndexType, IndexType, bool = false);
bool update(IndexType, DataType, IndexType, bool = false);
void clear() { name2dex.clear(); dex2name.clear(); mat.clear(); }
DataType shortestpath(IndexType,IndexType);
std::pair<bool, std::vector<IndexType>> topologicalsort();
~Graph() {}
};
template <typename IndexType,typename DataType>
Graph<IndexType,DataType>::Graph(std::vector<IndexType>& name, std::vector<std::vector<DataType>>& m) {
if (name.size() != m.size())return;
int num = name.size();
if (num <= 0)return;
mat = m;
for (int i = 0; i < num; i++) {
name2dex.insert(std::pair<IndexType, int>(name[i], i + 1));
dex2name.insert(std::pair<int, IndexType>(i + 1, name[i]));
}
}
template <typename IndexType, typename DataType>
Graph<IndexType, DataType>::Graph(const Graph& g) {
name2dex = g.name2dex;
dex2name = g.dex2name;
mat = g.mat;
}
template <typename IndexType, typename DataType>
Graph<IndexType, DataType>& Graph<IndexType, DataType>::operator=(const Graph& g) {
name2dex = g.name2dex;
dex2name = g.dex2name;
mat = g.mat;
return *this;
}
template <typename IndexType, typename DataType>
Graph<IndexType, DataType>::Graph(Graph&& g) {
name2dex = std::move(g.name2dex);
dex2name = std::move(g.dex2name);
mat = std::move(g.mat);
}
template <typename IndexType, typename DataType>
Graph<IndexType, DataType>& Graph<IndexType, DataType>::operator=(Graph&& g) {
name2dex = std::move(g.name2dex);
dex2name = std::move(g.dex2name);
mat = std::move(g.mat);
return *this;
}
template <typename IndexType,typename DataType>
bool Graph<IndexType,DataType>::insert(IndexType s, DataType dist, IndexType e, bool t) {
int sdex = name2dex[s], edex = name2dex[e];
if (!sdex || !edex) {
if (!sdex) {
sdex = dex2name.size() + 1;
name2dex[s] = sdex;
dex2name[sdex] = s;
}
if (!edex) {
edex = dex2name.size() + 1;
name2dex[e] = edex;
dex2name[edex] = e;
}
mat.resize(name2dex.size());
for (int i = 0; i < mat.size(); i++) { mat[i].resize(mat.size()); }
mat[sdex - 1][edex - 1] = dist;
if (t)mat[edex - 1][sdex - 1] = dist;
}
else {
if (mat[sdex - 1][edex - 1])return false;
mat[sdex - 1][edex - 1] = dist;
if (t)mat[edex - 1][sdex - 1] = dist;
}
return true;
}
template <typename IndexType,typename DataType>
bool Graph<IndexType,DataType>::del(IndexType s, IndexType e, bool t) {
int sdex = name2dex[s], edex = name2dex[e];
if (!sdex && !edex)return false;
mat[sdex - 1][edex - 1] = 0;
if(t)mat[edex - 1][sdex - 1] = 0;
return true;
}
template <typename IndexType,typename DataType>
bool Graph<IndexType,DataType>::update(IndexType s, DataType dist, IndexType e, bool t) {
int sdex = name2dex[s], edex = name2dex[e];
if (!sdex && !edex)return false;
mat[sdex - 1][edex - 1] = dist;
if(t)mat[edex - 1][sdex - 1] = dist;
return true;
}
template <typename IndexType,typename DataType>
DataType Graph<IndexType, DataType>::shortestpath(IndexType s, IndexType e) {
int sdex = name2dex[s], edex = name2dex[e];
//std::cout << "Calculate Path... start:" << sdex << " end:" << edex << std::endl;
if (!sdex || !edex)return 0;
if (sdex == edex)return mat[sdex - 1][edex - 1];
std::vector<bool> set(mat.size(), false);//confirm point
std::vector<DataType> dis(mat.size(), 0);//distance
std::priority_queue<nodedist> que;//priority_queue
que.push(nodedist(sdex-1,0));
while (!que.empty()) {
int index = que.top().index;
DataType dist = que.top().dist;
que.pop();
//std::cout << "current point:" << dex2name[index + 1] << " ";
if (set[index])continue;//has confirmed
if (index == edex - 1)return dist;
set[index] = true;
dis[index] = dist;
for (int i = 0; i < mat.size(); i++) {
if (mat[index][i])que.push(nodedist(i,dist+mat[index][i]));
}
}
return dis[edex - 1];
}
template <typename IndexType,typename DataType>
void Graph<IndexType,DataType>::show() {
std::cout << " ";
for (int i = 0; i < mat.size(); i++) {
std::cout << dex2name[i + 1] << " ";
}
std::cout << std::endl;
for (int i = 0; i < mat.size(); i++) {
std::cout << dex2name[i + 1] << " ";
for (int j = 0; j < mat.size(); j++) {
std::cout << mat[i][j] << " ";
}
std::cout << std::endl;
}
}
template <typename IndexType,typename DataType>
std::pair<bool, std::vector<IndexType>> Graph<IndexType, DataType>::topologicalsort() {
std::pair<bool, std::vector<IndexType>> ans(false,std::vector<IndexType>());
std::queue<int> my_que;
std::vector<int> indegrees(mat.size(), 0);
int num = mat.size();
for (int i = 0; i < mat.size(); i++) {
for (int j = 0; j < mat.size(); j++) {
if (mat[j][i])indegrees[i]++;
}
}
for (int i = 0; i < indegrees.size(); i++)if (!indegrees[i]) { my_que.push(i); ans.second.push_back(dex2name[i+1]); }
while (!my_que.empty()) {
int index = my_que.front();
my_que.pop();
for (int i = 0; i < mat.size(); i++) {
if (mat[index][i]) {
if (--indegrees[i] == 0) { my_que.push(i); ans.second.push_back(dex2name[i+1]); }
}
}
num--;
}
ans.first = (num == 0);
return ans;
}
#endif
来源:CSDN
作者:QinDiY
链接:https://blog.csdn.net/qq_35260990/article/details/104226401