一、图的有关概念
图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E)
图分为无向图和有向图。
#pragma once
#include
#include
using namespace std;
#include
template
class Graph
{
public:
Graph(V *array, size_t size)
:_v(array, array + size)
{
/*v.resize(size);
for (size_t i = 0; i < size; ++i)
{
_v[i] = array[i];
}*/
//边的空间
_edges.resize(size);
for (size_t i = 0; i < size; i++)
_edges[i].resize(size);
}
//寻找顶点元素在数组中的下标
size_t GetIndexOfV(const V& v)
{
for (size_t i = 0; i < _v.size(); ++i)
{
if (v == _v[i])
return i;
}
//找不到,出错
assert(false);
return -1;
}
//求顶点的度
size_t GetDevOfV(const V& v)
{
size_t index = GetIndexOfV(v);
size_t count = 0;
for (size_t i = 0; i < _v.size(); i++)
{
if (_edges[index][i])
count++;
}
if (IsDirect)
{
//有向图
for (size_t i = 0; i < _v.size(); ++i)
{
if (_edges[i][index])
count++;
}
}
return count;
}
//带权值的边
void AddEdge(const V& v1, const V& v2, const W& weight)
{
size_t index1 = GetIndexOfV(v1);
size_t index2 = GetIndexOfV(v2);
_edges[index1][index2] = weight;
if (!IsDirect)
_edges[index2][index1] = weight;
}
void PrintGraph()
{
size_t n = _v.size();
for (size_t i = 0; i _v; //顶点
vector> _edges; //边
};
void TestGraph()
{
char *pStr = "ABCDE";
Graph g(pStr, strlen(pStr));
g.AddEdge('A', 'D', 10);
g.AddEdge('A', 'E', 20);
g.AddEdge('B', 'C', 10);
g.AddEdge('B', 'D', 20);
g.AddEdge('B', 'E', 30);
g.AddEdge('C', 'E', 40);
g.PrintGraph();
cout << g.GetDevOfV('B') << endl;
}
template
struct Node
{
Node *_pNext;
W _weight;
size_t _src;
size_t _dst; //终点的下标
Node(size_t src, size_t dst, const W& weigt)
:_src(src)
, _dst(dst)
, _weight(_weight)
, _pNext(NULL)
{}
};
template < class V, class W,bool IsDirect=false>
class Graph
{
typedef Node Node;
typedef Node* pNode;
public:
Graph(const V* array, size_t size)
:_v(array,array+size)
{
_linkEdges.resize(size);
}
//寻找顶点元素在数组中的下标
size_t GetIndexOfV(const V& v)
{
for (size_t i = 0; i < _v.size(); ++i)
{
if (v == _v[i])
return i;
}
//找不到,出错
assert(false);
return -1;
}
//加边
void AddEdge(const V& v1, const V& v2,const W& weight)
{
size_t src = GetIndexOfV(v1);
size_t dst = GetIndexOfV(v2);
//头插,检测是否重复插入
_AddEdge(src, dst, weight);
if (!IsDirect)
_AddEdge(dst, src, weight);
}
//求顶点的度
size_t GetDevOfV(const V& v)
{
size_t count = 0;
size_t src = GetIndexOfV(v);
pNode pCur = _linkEdges[src];
//出度
while (pCur)
{
count++;
pCur = pCur->_pNext;
}
//入度
if (!IsDirect)
{
for (size_t i = 0; i < _v.size(); ++i)
{
pNode pTmp = _linkEdges[i];
while (pTmp)
{
if (_linkEdges[i]->_dst == src)
count++;
pTmp = pTmp->_pNext;
}
}
}
return count;
}
void PrintGraph()
{
size_t n = _v.size();
for (size_t i = 0; i < n; ++i)
{
cout << _v[i] << " ";
}
cout << endl;
for (size_t i = 0; i < _v.size(); ++i)
{
pNode pTmp = _linkEdges[i];
if (pTmp)
{
cout << pTmp->_src << " ";
while (pTmp)
{
cout << pTmp->_dst << " ";
pTmp = pTmp->_pNext;
}
cout << endl;
}
}
}
private:
void _AddEdge(size_t src, size_t dst, const W& weight)
{
//找链表
pNode pCur = _linkEdges[src];
while (pCur)
{
if (pCur->_dst == dst)
return;
pCur = pCur->_pNext;
}
//头插
pNode pNewNode = new Node(src, dst, weight);
pNewNode->_pNext = _linkEdges[src];
_linkEdges[src] = pNewNode;
}
private:
vector _v;
vector _linkEdges;
};
void TestGraph()
{
char *pStr = "ABCDE";
Graph g(pStr, strlen(pStr));
g.AddEdge('A', 'D', 10);
g.AddEdge('A', 'E', 20);
g.AddEdge('B', 'C', 10);
g.AddEdge('B', 'D', 20);
g.AddEdge('B', 'E', 30);
g.AddEdge('C', 'E', 40);
g.PrintGraph();
cout << g.GetDevOfV('A') << endl;
}