用C++实现图的DFS和BFS(邻接表)

概述

  图的储存方式有邻接矩阵和邻接表储存两种。由于邻接表的实现需要用到抽象数据结构里的链表,故稍微麻烦一些。C++自带的STL可以方便的实现List,使算法的实现变得简单起来

算法概述



  为了让我们的算法更有普适性,我们将非连通图也考虑在内。其实,要想遍历到类似于图中5,6节点这种孤岛节点,只需要依次按编号遍历顺序所有节点,如果某节点没有访问(book数组标记值为0),则从该节点开始深度优先搜索或广度优先搜索;等一次深搜或广搜完毕后,继续依次按照编号顺序遍历节点,选择从一个没访问过的结点开始再次深搜或广搜。。。如此知道把所有节点都遍历完。

代码

1.图抽象数据类型的声明,除了构造函数和析构函数之外,提供3个对外接口,分别实现递归DFS,BFS和非递归DFS(用STL栈实现)

using namespace std;
struct Graph{
//储存节点的邻接表
vector<list<int>> vertex;
//标记数组
bool book[100];
//n代表总节点个数
Graph(int n);
~Graph(); //对外接口,算法的驱动函数
void DFS_recursion_boost();
void BFS_boost();
void DFS_stack_boost(); private://内部算法实现
void DFS_recursion(int cur);
void BFS(int cur);
void DFS_stack(int cur); };

2.图的构造函数和析构函数实现

Graph::Graph(int n){
vertex.resize(n);
for(int i=0;i<n;++i){
int adj;
cout<<"请输入"<<i<<"号节点邻接链表(以-1表示结束输入)"<<endl;
cin>>adj;
while(adj!=-1){
vertex[i].push_back(adj);
cin>>adj;
}
}
memset(book,0,sizeof(book));
}
Graph::~Graph(){
vertex.clear();
}

3.图的递归DFS调用接口及其实现函数

void Graph::DFS_recursion_boost(){
for(int i=0;i<vertex.size();++i){
DFS_recursion(i);
}
} void Graph::DFS_recursion(int cur){
if(book[cur]==1) return;
book[cur]=1;
cout<<cur;
for(auto iter=vertex[cur].begin();iter!=vertex[cur].end();++iter){
if(book[*iter]==0){
DFS_recursion(*iter);
}
}
}

4.图的BFS调用接口及其实现函数


void Graph::BFS_boost(){
for(int i=0;i<vertex.size();++i){
BFS(i);
}
}
void Graph::BFS(int cur){
queue<int> q;
if(book[cur]==0){
q.push(cur);
}
while(!q.empty()){
int front=q.front();
q.pop();
cout<<front;
book[front]=1;
for(auto iter=vertex[front].begin();iter!=vertex[front].end();++iter){
if(book[*iter]==0){
q.push(*iter);
}
}
}
}

5.图的非递归DFS及其实现函数

void Graph::DFS_stack_boost(){
for(int i=0;i<vertex.size();++i){
DFS_stack(i);
}
}
void Graph::DFS_stack(int cur)
{
stack<int> s;
if(book[cur]==0){
s.push(cur);
}
while(!s.empty()){
int top=s.top();
if(book[top]==0){
book[top]=1;
cout<<top;
}
else{
s.pop();
// top=s.top();为何不要?
}
for(auto iter=vertex[top].begin();iter!=vertex[top].end();++iter){
if(book[*iter]==0){
s.push(*iter);
break;
}
}
}
}

6.主函数测试(注意,每次遍历后要把标记数组初始化为0)

int main(){
Graph G(7); cout<<"递归DFS:"<<endl;
G.DFS_recursion_boost();
memset(G.book,0,100);
cout<<endl; cout<<"BFS:"<<endl;
G.BFS_boost();
memset(G.book,0,100);
cout<<endl; cout<<"非递归BFS:"<<endl;
G.DFS_stack_boost();
memset(G.book,0,100);
cout<<endl;
system("pause");
return 0; }

输出

图的DFS和BFS(邻接表)的更多相关文章

  1. 数据结构(11) -- 邻接表存储图的DFS和BFS

    /////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS //////////////// ...

  2. 图的DFS与BFS

    图的DFS与BFS(C++) 概述 大一学生,作为我的第一篇Blog,准备记录一下图的基本操作:图的创建与遍历.请大佬多多包涵勿喷. 图可以采用邻接表,邻接矩阵,十字链表等多种储存结构进行储存,这里为 ...

  3. Java数据结构——图的DFS和BFS

    1.图的DFS: 即Breadth First Search,深度优先搜索是从起始顶点开始,递归访问其所有邻近节点,比如A节点是其第一个邻近节点,而B节点又是A的一个邻近节点,则DFS访问A节点后再访 ...

  4. 【数据结构】【图文】【oj习题】 图的拓扑排序(邻接表)

    拓扑排序: 按照有向图给出的次序关系,将图中顶点排成一个线性序列,对于有向图中没有限定次序关系的顶点,则可以人为加上任意的次序关系,由此所得顶点的线性序列称之为拓扑有序序列.显然对于有回路的有向图得不 ...

  5. 图的基本操作(基于邻接表):图的构造,深搜(DFS),广搜(BFS)

    #include <iostream> #include <string> #include <queue> using namespace std; //表结点 ...

  6. [数据结构]图的DFS和BFS的两种实现方式

    深度优先搜索 深度优先搜索,我们以无向图为例. 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发, ...

  7. 图的DFS与BFS遍历

    一.图的基本概念 1.邻接点:对于无向图无v1 与v2之间有一条弧,则称v1与v2互为邻接点:对于有向图而言<v1,v2>代表有一条从v1到v2的弧,则称v2为v1的邻接点. 2.度:就是 ...

  8. bfs 邻接表(需要优化 可能会RE *【模板】)

    //---基于邻接表的bfs #include <stdio.h> #include <string.h> #include <iostream> #include ...

  9. hdu 4707 Pet(DFS &amp;&amp; 邻接表)

    Pet Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

随机推荐

  1. ajax原生js封装

    不带注释的 function ajax(json) { json.type = json.type ? json.type : 'get'; json.async = json.async == fa ...

  2. 波士顿动力狗 SPOT 权威购买指北

    两周前 油管科技视频播主 Lew Later 发布了一支 波士顿动力狗子的开箱视频,短短两周的时间内这支视频的播放量就达到了367万, 在Lew Later 近期发布的视频中,这支视频的播放量绝对算得 ...

  3. [spring cloud] -- 核心篇

    核心功能: 分布式/版本化配置 服务注册合发现 服务路由 服务和服务之间的调用 负载均衡 断路器 分布式消息传递 ...... 技术体系 组件 服务注册与发现组件:Eureka.Zookeeper和C ...

  4. django-rest-framework-源码解析002-序列化/请求模块/响应模块/异常处理模块/渲染模块/十大接口

    简介 当我们使用django-rest-framework框架时, 项目必定是前后端分离的, 那么前后端进行数据交互时, 常见的数据类型就是xml和json(现在主流的是json), 这里就需要我们d ...

  5. 像计算机科学家一样思考Python(第2版)|百度网盘免费下载|Python新手入门资料

    像计算机科学家一样思考Python(第2版)|百度网盘免费下载 提取码:01ou 内容简介  · · · · · · 本书以培养读者以计算机科学家一样的思维方式来理解Python语言编程.贯穿全书的主 ...

  6. Android上传图片的两种方式

    参考:https://www.jianshu.com/p/f47943880cea

  7. 数据结构C语言实现----树

    树的基本知识点 树的定义 树的ADT(抽象数据类型) 树的储存结构 二叉树的定义 二叉树的储存结构 遍历二叉树 二叉树的建立 二叉树的ADT typedef struct BiTNode { Elem ...

  8. 微服务迁移记(五):WEB层搭建(3)-FreeMarker集成

    一.redis搭建 二.WEB层主要依赖包 三.FeignClient通用接口 以上三项,参考<微服务迁移记(五):WEB层搭建(1)> 四.SpringSecurity集成 参考:< ...

  9. Python List len()方法

    描述 len() 方法返回列表元素个数.高佣联盟 www.cgewang.com 语法 len()方法语法: len(list) 参数 list -- 要计算元素个数的列表. 返回值 返回列表元素个数 ...

  10. PHP password_needs_rehash() 函数

    password_hash() 函数用于检测散列值是否匹配指定的选项. PHP 版本要求: PHP 5 >= 5.5.0, PHP 7高佣联盟 www.cgewang.com 语法 bool p ...