这里实现图的两种存储结构——邻接矩阵与邻接表。
邻接矩阵
用邻接矩阵存储图需要用到两个数组——一个存储元素的一维数组和一个存储图关系的二维数组。其实现代码:
template<typename V, bool IsDigraph = true>
class Map
{
public:
Map(const string str = "")
{
size_t size = str.length();
_v.resize(size);
for(size_t i = 0; i < size; i++)
_v[i] = str[i];
_map.resize(size);
for(size_t i = 0; i < size; i++)
_map[i].resize(size, 0);
}
bool InsertEdge(const V& origin, const V& terminus, const int& weight)
{
int originSub = FindSub(origin);
int terminuSub = FindSub(terminus);
if(originSub == terminuSub || originSub < 0 || terminuSub < 0)
return false;
_map[originSub][terminuSub] = weight;
if(!IsDigraph)
_map[terminuSub][originSub] = weight;
return true;
}
int FindSub(const V& value)
{
size_t size = _v.size();
for(size_t i = 0; i < size; i++)
if(value == _v[i])
return i;
return -1;
}
void PrintMap()
{
size_t size = _v.size();
cout << " ";
for(size_t i = 0; i < size; i++)
cout << " " << _v[i];
cout << endl;
for(size_t i = 0; i < size; i++)
{
cout << _v[i];
for(size_t j = 0; j < size; j++)
cout << " " << _map[i][j];
cout << endl;
}
}
private:
vector<V> _v;
vector<vector<int> > _map;
};
可建立有向图或者无向图。
先建立一个无向图:
void test()
{
Map<char, false> m("ABCDEFG");
m.InsertEdge('A', 'B', 3);
m.InsertEdge('A', 'D', 5);
m.InsertEdge('C', 'B', 3);
m.InsertEdge('C', 'G', 4);
m.InsertEdge('D', 'F', 1);
m.InsertEdge('G', 'E', 6);
m.InsertEdge('F', 'C', 7);
m.PrintMap();
}
运行结果:
建立有向图:
void test()
{
Map<char> m("ABCDEFG");
m.InsertEdge('A', 'B', 3);
m.InsertEdge('A', 'D', 5);
m.InsertEdge('C', 'B', 3);
m.InsertEdge('C', 'G', 4);
m.InsertEdge('D', 'F', 1);
m.InsertEdge('G', 'E', 6);
m.InsertEdge('F', 'C', 7);
m.PrintMap();
}
运行结果:
邻接表
邻接表由一个存储元素的一维数组和一个带链表的一维数组组成,其结构图可抽象为:
实现代码:
template <typename V>
struct MapNode
{
V _value;
int _weight;
MapNode* _Next;
MapNode(const V& value = V(), const int& weight = 0)
: _value(value)
, _weight(weight)
, _Next(NULL)
{}
};
template <typename V, bool IsDigraph = true>
class Map
{
typedef MapNode<int> Node;
typedef Node* PNode;
public:
Map(const string str = "")
{
size_t size = str.length();
_v.resize(size);
for(size_t i = 0; i < size; i++)
_v[i] = str[i];
_map.resize(size);
for(size_t i = 0; i < size; i++)
_map[i]._value = i;
}
bool InsertEdge(const V& origin, const V& terminus, const int& weight)
{
int originSub = FindSub(origin);
int terminuSub = FindSub(terminus);
if(originSub == terminuSub || originSub < 0 || terminuSub < 0)
return false;
PNode pCur = &_map[originSub];
while(pCur->_Next)
pCur = pCur->_Next;
pCur->_Next = new Node(terminuSub, weight);
if(!IsDigraph)
{
pCur = &_map[terminuSub];
while(pCur->_Next)
pCur = pCur->_Next;
pCur->_Next = new Node(originSub, weight);
}
return true;
}
int FindSub(const V& key)
{
size_t size = _v.size();
for(size_t i = 0; i < size; i++)
if(key == _v[i])
return i;
return -1;
}
void PrintMap()
{
size_t size = _v.size();
if(size < 1)
return;
for(size_t i = 0; i < size; i++)
{
if(_map[i]._Next)
{
cout << _v[i];
PNode pCur = _map[i]._Next;
while(pCur)
{
cout << "-->" << _v[pCur->_value] << "(" << pCur->_weight << ")";
pCur = pCur->_Next;
}
cout << endl;
}
}
}
private:
vector<V> _v;
vector<Node> _map;
};
有向图:
void test()
{
Map<char> m("ABCDEFG");
m.InsertEdge('A', 'B', 3);
m.InsertEdge('A', 'D', 5);
m.InsertEdge('C', 'B', 3);
m.InsertEdge('C', 'G', 4);
m.InsertEdge('D', 'F', 1);
m.InsertEdge('G', 'E', 6);
m.InsertEdge('F', 'C', 7);
m.PrintMap();
}
运行:
无向图:
void test()
{
Map<char, false> m("ABCDEFG");
m.InsertEdge('A', 'B', 3);
m.InsertEdge('A', 'D', 5);
m.InsertEdge('C', 'B', 3);
m.InsertEdge('C', 'G', 4);
m.InsertEdge('D', 'F', 1);
m.InsertEdge('G', 'E', 6);
m.InsertEdge('F', 'C', 7);
m.PrintMap();
}
运行: