用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. .Net Core+Nginx实现项目负载均衡

    nginx大家如果没用过那或多或少都应该听过,vue的部署.反向代理.负载均衡nginx都能帮你做到. 今天主要说一下nginx负载均衡我们的项目,如下图所示,请求到达nginx,nginx再帮我们转 ...

  2. 最简单的VScode Python 开发环境配置以及中文化

    前置条件 Python 3.X(2020年了,建议使用Python3.X版本) 一.下载VSCode VSCode官方下载链接 由于安装过程是中文界面,此处略过. 二.VSCode中文化 不需要配置什 ...

  3. .Net Core in Docker极简入门(上篇)

    目录 前言 开始 环境准备 Docker基础概念 Docker基础命令 Docker命令实践 构建Docker镜像 Dockerfile bulid & run 前言 Docker 是一个开源 ...

  4. 商品表(spu)、规格表(sku)设计

    1. 先做一下专业术语解释:spu和sku 这里拿iphone6s举例,它身上有很多的属性和值, 比如: 毛重: 420.00 g 产地: 中国大陆 容量: 16G, 64G, 128G 颜色: 银, ...

  5. Horse Pro(带负坐标的bfs搜索)

    Horse Pro bfs搜索,但图中存在负值坐标,两种方法解决. 用数组标记,将原点设为300,300 用map标记 http://oj.jxust.edu.cn/contest/Problem?i ...

  6. javascript 通信协议

    简介 javascript 通信协议是一个伪协议[1], 用于指定 URL 为 JavaScript 代码 语法: javascript:someScript; someScript 是一个或多个使用 ...

  7. jmeter混合场景的多种实现方式比较

    性能测试设计混合场景,一般有几种方式,分别是每个场景设置一个线程组,使用if控制器,使用吞吐量控制器.不同的方式实现机制不一样,哪种方式相比而言更好呢?下面做一比较. 下面以混合访问百度首页和必应首页 ...

  8. Python匿名函数_return语句

    Python匿名函数: 使用 lambda 关键字创建匿名函数: lambda 定义的函数只是一个表达式,而不是代码块 lambda 函数拥有自己的命名空间,不能够访问参数列表之外的 或 全局命名空间 ...

  9. 牛客练习赛60 E 旗鼓相当的对手

    LINK:旗鼓相当的对手 考场上遇到这种简单的树形dp优化题目我真的不一定能写出来.. 虽然这道题思路很简单 设f[i][j]表示距i距离为j的点的个数 g[i][j]表示距i距离为j的点权和. 可以 ...

  10. 大话Android中的Handler机制

    在Android的线程间通信中,Handler独当一面,无论是framework层还是app层中都出现的相当频繁,有必要好好的拿出来深挖一下它的实现原理.而要说Handler的通信机制,除了Handl ...