图的存储

图 : 是一种线性结构,由顶点集合(vertex)及顶点间的关系集合组成的一种数据结构。

图的存储:
临接矩阵:将所有的顶点的信息组织成一个顶点表,然后利用矩阵来表示各顶点之间的临接关系,称为临接矩阵。

邻接表:使用数组存储顶点集合,使用链表链接边的关系。

图的邻接矩阵存储实现代码:

#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();
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值