図の記憶
図:頂点セット(vertex)と頂点間の関係セットからなる線形構造.
図の記憶:臨接行列:すべての頂点の情報を1つの頂点テーブルに整理し、各頂点間の臨接関係を行列で表し、臨接行列と呼ぶ.
隣接テーブル:配列を使用して頂点セットを格納し、チェーンテーブルを使用してエッジの関係をリンクします.
図の隣接マトリクス記憶実装コード:
テスト例:
図の隣接表は実現コードを記憶する:
テスト例:
図の記憶:臨接行列:すべての頂点の情報を1つの頂点テーブルに整理し、各頂点間の臨接関係を行列で表し、臨接行列と呼ぶ.
隣接テーブル:配列を使用して頂点セットを格納し、チェーンテーブルを使用してエッジの関係をリンクします.
図の隣接マトリクス記憶実装コード:
#pragma once
#include<assert.h>
template<class V, class W>
class GraphMatrix
{
public:
GraphMatrix(const V* vArray, int size, bool IsDigraph = false)
:_vArray(new V[size])
, _vSize(size)
, IsDigraph(IsDigraph)
{
_Matrix = new W*[_vSize];
for (int i = 0; i < size; ++i)
{
_vArray[i] = vArray[i];
_Matrix[i] = new W[_vSize];
memset(_Matrix[i], 0, sizeof(W)*_vSize);
}
}
int GetVertexIndex(const V& vt)
{
for (int i = 0; i < _vSize; ++i)
{
if (_vArray[i] == vt)
{
return i;
}
}
return -1;
}
void AddEdge(const V& src, const V& dst, const W& weight)
{
int srcIndex = GetVertexIndex(src);
int dstIndex = GetVertexIndex(dst);
assert(srcIndex != -1);
assert(dstIndex != -1);
if (IsDigraph)
{
_Matrix[srcIndex][dstIndex] = weight;
}
else
{
_Matrix[srcIndex][dstIndex] = weight;
_Matrix[dstIndex][srcIndex] = weight;
}
}
void Display()
{
for (int i = 0; i < _vSize; ++i)
{
cout << _vArray[i] << " ";
}
cout << endl;
for (int i = 0; i < _vSize; ++i)
{
for (int j = 0; j < _vSize; ++j)
{
cout << _Matrix[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
~GraphMatrix()
{
if (_vArray != NULL)
{
delete[] _vArray;
_vArray = NULL;
for (int i = 0; i < _vSize; ++i)
{
delete[] _Matrix[i];
_Matrix[i] = NULL;
}
delete[] _Matrix;
_Matrix = NULL;
}
}
private:
V* _vArray; //
int _vSize; //
W** _Matrix; //
bool IsDigraph;
};
テスト例:
void TestGraphMatrix1()
{
GraphMatrix<char, int> gm("ABCDE", 5);
gm.AddEdge('A', 'D', 10);
gm.AddEdge('A', 'E', 20);
gm.AddEdge('B', 'C', 10);
gm.AddEdge('B', 'D', 20);
gm.AddEdge('B', 'E', 30);
gm.AddEdge('C', 'E', 40);
gm.Display();
}
//
void TestGraphMatrix2()
{
GraphMatrix<char, int> gm("ABCDE", 5, true);
gm.AddEdge('A', 'D', 10);
gm.AddEdge('E', 'A', 20);
gm.AddEdge('B', 'C', 10);
gm.AddEdge('D', 'B', 20);
gm.AddEdge('E', 'B', 30);
gm.AddEdge('C', 'E', 40);
gm.Display();
}
図の隣接表は実現コードを記憶する:
#pragma once
template<class V, class W>
struct LinkEdge
{
W _w;
size_t _srcIndex;
size_t _dstIndex;
LinkEdge<V, W>* _next;
LinkEdge(size_t srcIndex, size_t dstIndex, const W& w)
: _w(w)
, _srcIndex(srcIndex)
, _dstIndex(dstIndex)
, _next(NULL)
{}
};
template<class V, class W>
struct LinkVertex
{
V _vertex;
LinkEdge<V, W>* _head;
LinkVertex(const V& vertex = V())
:_vertex(vertex)
, _head(NULL)
{}
};
template<class V, class W>
class GraphLink
{
public:
GraphLink(const V* vArray, int size, bool IsDigraph = false)
:_vSize(size)
, _IsDigraph(IsDigraph)
{
_LinkTable = new LinkVertex<V, W>[size];
for (int i = 0; i < size; i++)
{
_LinkTable[i]._vertex = vArray[i];
}
}
public:
void AddEdge(const V& src, const V& dst, const W& weight)
{
int srcIndex = GetVertexIndex(src);
int dstIndex = GetVertexIndex(dst);
assert(srcIndex != -1);
assert(dstIndex != -1);
if (_IsDigraph)
{
_AddEdge(srcIndex, dstIndex, weight);
}
else
{
_AddEdge(srcIndex, dstIndex, weight);
_AddEdge(dstIndex, srcIndex, weight);
}
}
void Display()
{
for (int i = 0; i < _vSize; i++)
{
cout << _LinkTable[i]._vertex << "[" << i << "]->";
LinkEdge<V, W>* cur = _LinkTable[i]._head;
while (cur != NULL)
{
cout << cur->_w << "[" << cur->_dstIndex << "]->";
cur = cur->_next;
}
cout << "NULL" << endl;
}
cout << endl;
}
protected:
int GetVertexIndex(const V& vertex)
{
for (int i = 0; i < _vSize; i++)
{
if (_LinkTable[i]._vertex == vertex)
{
return i;
}
}
return -1;
}
void _AddEdge(const V& srcIndex, const V& dstIndex, const W& weight)
{
LinkEdge<V, W>* head = _LinkTable[srcIndex]._head;
LinkEdge<V, W>* tmp = new LinkEdge<V, W>(srcIndex, dstIndex, weight);
tmp->_next = head;
_LinkTable[srcIndex]._head = tmp;
}
private:
LinkVertex<V, W>* _LinkTable;
int _vSize;
bool _IsDigraph;
};
テスト例:
//
void TestGraphLink1()
{
GraphLink<char, int> gl("ABCDE", 5);
gl.AddEdge('A', 'D', 10);
gl.AddEdge('A', 'E', 20);
gl.AddEdge('B', 'C', 10);
gl.AddEdge('B', 'D', 20);
gl.AddEdge('B', 'E', 30);
gl.AddEdge('C', 'E', 40);
gl.Display();
}
//
void TestGraphLink2()
{
GraphLink<char, int> gl("ABCDE", 5, true);
gl.AddEdge('A', 'D', 10);
gl.AddEdge('E', 'A', 20);
gl.AddEdge('B', 'C', 10);
gl.AddEdge('D', 'B', 20);
gl.AddEdge('E', 'B', 30);
gl.AddEdge('C', 'E', 40);
gl.Display();
}