C++实现图的广度优先BFS算法和深度优先DFS的(递归非递归)算法


0 图的遍历

图的遍历图和树的遍历类似,那就是从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这个过程就叫做图的遍历。

对于图的遍历来说,如何避免因回路陷入死循环,就需要科学地设计遍历方案,通过有两种遍历次序方案:深度优先遍历和广度优先遍历。

1 DFS算法思想

深度优先遍历(Depth_First_Search),也称为深度优先搜索,简称DFS。

在这里插入图片描述

2 BFS算法思想

广度优先遍历(Breadth_First_Search),又称为广度优先搜索,简称BFS。

在这里插入图片描述

3 代码实现

//Graph header file.
#ifndef _GRAPH_H
#define _GRAPH_H
#include "cComHead.h"
#if Graph_dfsbfs_ctrol
#include <iostream>
#include <cstdio>
#include <list>
#include <vector>
#include <queue>
#include <stack>
#include <fstream>
using namespace std;

template <class T>
class graph
{
private:
    T n;
    vector<list<T>> _graph;
    bool visited[100] = {0};
    /* data */
public:
    graph(/* args */);
    ~graph();
    //Creat graph
    void creatGraph();
    void creatGraph(const char*);
    //DFS Recursion
    void dfs(const T&);
    //DFS no Recursion
    void dfs_noRec(const T&);
    //BFS no Recursion
    void bfs_noRec(const T&);
};
template <class T>
graph<T>::graph(/* args */)
{
}
template <class T>
graph<T>::~graph()
{
}
#endif
#endif /*graph.h*/
  1. 代码中采用邻接表的方式存储图,定义形式为vector<list<T>>.
  2. 创建图采用了两种方式,一种是手动输入数据creatGraph(),另一种是文本方式导入数据creatGraph(const char*)。具体实现方法如下:
template <class T>
void graph<T>::creatGraph()
{
    cout << "input the vertex num:" << endl;
    cin >> n;
    //vector<list<T>>::iterator it;
    for (int i = 0; i < n; ++i)
    {
        list<T> i1;
        T t;
        while (cin >> t && t != n) //输入每个顶点相连的图,以最终节点为结束标志
            i1.push_back(t);
        _graph.push_back(i1);
    }
}
template <class T>
void graph<T>::creatGraph(const char *fp)
{
    ifstream in(fp);
    in >> n;
    cout << "input the vertex num:" << n << endl;
    for (int i = 0; i < n; i++)
    {
        /* code */
        list<T> i1;
        T t;
        while (in >> t && t != n) //输入每个顶点相连的图,以最终节点为结束标志
            i1.push_back(t);
        _graph.push_back(i1);
    }
}
  1. 广度优先BFS算法采用非递归方式实现void bfs_noRec(const T&),借助了队列,具体实现方法如下:
template <class T>
void graph<T>::bfs_noRec(const T &ver)
{
    visited[ver] = true;
    cout << ver << "-->";
    queue<T> myqueue;
    myqueue.push(ver);
    while (!myqueue.empty())
    {
        /* code */
        T tempver = myqueue.front();
        myqueue.pop();

        for (auto it : _graph[tempver])
        {
            /* code */
            if (!visited[it])
            {
                cout << it << "-->";
                myqueue.push(it);
                visited[it] = true;
            }
        }
    }
    cout << "end!" << endl;
}
  1. 深度优先DFS算法采用递归和非递归两种方式实现void dfs(const T&)void dfs_noRec(const T&),其中非递归方式借助了栈,具体实现方法如下:
template <class T>
void graph<T>::dfs(const T &ver)
{
    visited[ver] = true;
    cout << ver << "-->";
    for (auto it : _graph[ver])
    {
        /* code */
        if (!visited[it])
            dfs(it);
    }
}
template <class T>
void graph<T>::dfs_noRec(const T &ver)
{
    visited[ver] = true;
    cout << ver << "-->";
    stack<T> mystack;
    mystack.push(ver);
    while (!mystack.empty())
    {
        /* code */
        T tempver = mystack.top();
        mystack.pop();
        if (!visited[tempver])
        {
            visited[tempver] = true;
            cout << tempver << "-->";
        }
        for (auto it : _graph[tempver])
        {
            /* code */
            if (!visited[it])
                mystack.push(it);
        }
    }
    cout << "end!" << endl;
}

4 测试

int main(int argc, char *argv[])
{
#if Graph_dfsbfs_ctrol
    graph<int> mygraph, mygraph1;
    mygraph.creatGraph("testdata.txt");
    mygraph1.creatGraph("testdata.txt");
    mygraph.bfs_noRec(0);
    mygraph1.dfs(0);
    cout << "end!" << endl;
#endif
}

博主在测试中才用了文本导入数据的方式,testdata.txt中存放测试数据,数据列表如下:

8
0 1 2 8
1 0 3 4 8
2 0 5 6 8
3 1 7 8
4 1 7 8
5 2 7 8
6 2 7 8
7 3 4 5 6 8

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

i胡说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值