临接矩阵
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
// 临接矩阵
template<class V,class W,size_t N,bool IsDirector=false>//IsDirector标记是无向图还是有向图,默认无向图
class GraphMartix
{
public:
GraphMartix()
{}
GraphMartix(V* vertix)
{
//此处不要用 memset进行初始化,它适合于内置类型
for (size_t i = 0; i < N; ++i)
{
_vertix[i] = vertix[i];
}
for (size_t i = 0; i < N; ++i)
{
for (size_t j = 0; j < N; ++j)
{
_martix[i][j] = W();
}
}
}
//添加边,已知两个顶点,以及权值
void AddEdge(const V& src,const V& dst,const W& w)
{
//先获取这两个点的位置
int srcIndex=_GetVertexIndex(src);
int desInndex=_GetVertexIndex(dst);
_martix[srcIndex][desInndex] = w;
//如果为无向图,则需要两个点互相都联通
if (IsDirector==false)
{
_martix[desInndex][srcIndex] = w;
}
}
int _GetVertexIndex(const V& tervex)
{
for (size_t i = 0; i < N; ++i)
{
if (_vertix[i] == tervex)
return i;
}
//按照设想,程序不应该走到这一步;如果到这里,说明该点没有被找到
//所以在此处我们采用防御式编程
assert(false);
return -1;
}
protected:
V _vertix[N];//顶点集
W _martix[N][N];//边集
};
void testMartix()
{
string add[] = {"school","house","park","market","hospital"};
GraphMartix<string,int, sizeof(add)/sizeof(add[0])> ghm(add);
ghm.AddEdge("school", "house",1000);
ghm.AddEdge( "house", "park",200);
ghm.AddEdge("market", "hospital",100);
ghm.AddEdge("park","hospital",700);
ghm.AddEdge("park", "market", 600);
}
临接矩阵
template<class W>
struct LinkEdge
{
W _w;//权重
int _src;//边上起始节点
int _dst;//边上目标节点
LinkEdge<W>* _next;
//在这里如果单纯实现临接表的话其实没有必要存目标节点
//是最小生成树的算法要用到dst节点
LinkEdge(int src,int dst,const W& w)
:_w(w)
,_src(src)
,_dst(dst)
, _next(NULL)
{}
};
template<class V, class W, size_t N, bool IsDirector = false>
class GraphLink
{
typedef LinkEdge<W> Edge;
public:
GraphLink()
{}
GraphLink(V* vertexs)
{
_vertexs.reserve(N);
for (size_t i = 0; i < N; ++i)
{
_vertexs.push_back(vertexs[i]);
}
_LinkTable.resize(N, NULL);
}
void AddEdge(const V& src,const V& dst,const W& w)
{
int srcIndex = _GetVertexIndex(src);
int dstIndex = _GetVertexIndex(dst);
//头插法向数组中插入节点
_AddEdge(srcIndex,dstIndex,w);
if (IsDirector == false)
{
_AddEdge(dstIndex,srcIndex,w);
}
}
int _GetVertexIndex(const V& vertex)
{
for (size_t i = 0; i < N; ++i)
{
if (_vertexs[i] ==vertex)
return i;
}
assert(false);
return -1;
}
void _AddEdge(int srcIndex,int dstIndex,const W& w)
{
Edge* edge = new Edge(srcIndex,dstIndex,w);
//头插
edge->_next = _LinkTable[srcIndex];
_LinkTable[srcIndex] = edge;
}
protected:
vector<V> _vertexs;//顶点集合
//边集的数组是指针数组
vector<Edge*> _LinkTable;//边集
};