有向图及深度广度遍历的简单实现
作者:Mrzhu007
日期:2019-05-18
博客地址:金色世界
注:以最少代码实现各种经典数据结构,了解数据结构的魅力,以C++语言描述,不处理异常情况
如无说明,引用的均为C++标准库中STL组件
Graph数据定义
// 采用简单的矩阵实现有向图的数据结构定义
typedef std::vector<std::vector<int>> __Array;
class CGraph
{
public:
CGraph(int nSize_ = 0)
: m_nNumVerter(nSize_), m_nNumEdge(0)
{
for(int _i = 0; _i < nSize_; ++_i)
{
std::vector<int> _temp;
m_Data.push_back(_temp);
for(int _j = 0; _j < nSize_;++_j)
{
m_Data.back().push_back(0);
}
}
}
~CGraph()
{
}
int NumberOfVertices() const
{
return m_nNumVertice;
}
int NumberOfEdges() const
{
return m_nNumEdge;
}
bool ExistsEdge(int i, int j) const
{
return m_Data[i][j] == 1;
}
void InsertEdge(int i, int j)
{
m_Data[i][j] = 1;
++m_nNumEdge;
}
void EraseEdge(int i ,int j)
{
m_Data[i][j] = 0;
--m_nNumEdge;
}
private:
int m_nNumVertice;
int m_nNumEdge;
__Array m_Data;
// 深度优先遍历
// 使用栈来记录图中得层次节点
friend void DFSTraverse(const CGraph& Graph_, std::vector<int>& stack_, int* pVisited_);
// 广度优先遍历
friend void BFSTraverse(const CGraph& Graph_, int nVerter_, int* pVisited_);
}
// 遍历算法实现
void DFSTraverse(const CGraph& Graph_, std::vector<int>& stack_, int* pVisited_)
{
if(stack_.empty())
return;
int _nVertice = stack_.back();
stack_.pop_back();
pVistited_[_nVertice] = 1;
std::cout << "到达顶点" << _nVertice << std::endl;
for(int _i = 0; _i < Graph_.m_nNumVertice; ++i)
{
// 下个顶点有边且没有被访问过
if(Graph_.m_Data[_nVertice][_i] == 1 && pVisited_[_i] != 1)
stack_.push_back(_i);
}
DFSTraverse(Graph_, stack_, pVisited_);
}
void BFSTraverse(const CGraph& Graph_, int nVerter_, int* pVisited_)
{
if(pVisited_[nVerter_] != 1)
{
std::cout << "到达顶点" << nVerter_ << std::endl;
pVisited_[nVerter_] = 1;
}
std::vector<int> _nVec;// 记录当前顶点的相邻顶点
for(int _i = 0; _i < Graph.m_nNumVertice; ++_i)
{
// 下个顶点有边且没有被访问过
if(Graph_.m_Data[nVerter][_i] == 1 && pVisited[_i] != 1)
{
std::cout << "到达顶点" << _i << std::endl;
pVisited_[_i] = 1;
_nVec.push_back(_i);
}
}
for(unsigned _i = 0; _i < _nVec.size(); ++_i)
BFSTraverse(Graph_, _nVec[_i], pVisiter_);
}
// 使用
int _tmain(int argc, _TCHAR* argv[])
{
// 图的初始形状如下
// 2--------5-------------
// | | |
//0---------1--------3------6-----8-----10
// \ | | | |
// \-------4------/-----7------9
CGraph _Graph(11);
_Graph.InsertEdge(0,1);
_Graph.InsertEdge(1,2);
_Graph.InsertEdge(1,3);
_Graph.InsertEdge(1,4);
_Graph.InsertEdge(2,5);
_Graph.InsertEdge(3,5);
_Graph.InsertEdge(3,4);
_Graph.InsertEdge(4,6);
_Graph.InsertEdge(4,7);
_Graph.InsertEdge(5,8);
_Graph.InsertEdge(6,8);
_Graph.InsertEdge(7,8);
_Graph.InsertEdge(7,9);
_Graph.InsertEdge(8,10);
_Graph.InsertEdge(9,10);
int _pVisiter[11] = {0};
std::vector<int> _stack;
std::cout << "深度优先" << std::endl;
DFSTraverse(_Graph, _stack, _pVisited);
std::cout << "广度优先" << std::endl;
memset(_pVisited, 0, sizeof(_pVisited));
BFSTraverse(_Graph, 0, _pVisited);
}