图的DFS和BFS(邻接表)
用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(邻接表)的更多相关文章
- 数据结构(11) -- 邻接表存储图的DFS和BFS
/////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS //////////////// ...
- 图的DFS与BFS
图的DFS与BFS(C++) 概述 大一学生,作为我的第一篇Blog,准备记录一下图的基本操作:图的创建与遍历.请大佬多多包涵勿喷. 图可以采用邻接表,邻接矩阵,十字链表等多种储存结构进行储存,这里为 ...
- Java数据结构——图的DFS和BFS
1.图的DFS: 即Breadth First Search,深度优先搜索是从起始顶点开始,递归访问其所有邻近节点,比如A节点是其第一个邻近节点,而B节点又是A的一个邻近节点,则DFS访问A节点后再访 ...
- 【数据结构】【图文】【oj习题】 图的拓扑排序(邻接表)
拓扑排序: 按照有向图给出的次序关系,将图中顶点排成一个线性序列,对于有向图中没有限定次序关系的顶点,则可以人为加上任意的次序关系,由此所得顶点的线性序列称之为拓扑有序序列.显然对于有回路的有向图得不 ...
- 图的基本操作(基于邻接表):图的构造,深搜(DFS),广搜(BFS)
#include <iostream> #include <string> #include <queue> using namespace std; //表结点 ...
- [数据结构]图的DFS和BFS的两种实现方式
深度优先搜索 深度优先搜索,我们以无向图为例. 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发, ...
- 图的DFS与BFS遍历
一.图的基本概念 1.邻接点:对于无向图无v1 与v2之间有一条弧,则称v1与v2互为邻接点:对于有向图而言<v1,v2>代表有一条从v1到v2的弧,则称v2为v1的邻接点. 2.度:就是 ...
- bfs 邻接表(需要优化 可能会RE *【模板】)
//---基于邻接表的bfs #include <stdio.h> #include <string.h> #include <iostream> #include ...
- hdu 4707 Pet(DFS && 邻接表)
Pet Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
随机推荐
- 数据库分布式事务XA规范介绍及Mysql底层实现机制
1. 引言 分布式事务主要应用领域主要体现在数据库领域.微服务应用领域.微服务应用领域一般是柔性事务,不完全满足ACID特性,特别是I隔离性,比如说saga不满足隔离性,主要是通过根据分支事务执行成功 ...
- xilinx fpga 生成3*3窗口
在写滤波程序的时候在网上看了好几篇大佬的笔记,都有提到使用3*3窗口,由于小白一个,看到复杂的理论就惧怕的不行.但是现在不得不上,自己调用移位寄存器ip核然后做了个3*3窗口出来,自己动手作出来忽然感 ...
- .Net Core Controller
[HttpGet] public async Task<ActionResult<IEnumerable<ABBUserModel>>> GetUser() { / ...
- methodology of english learning
classify the vocabulary into different catigories syllabus about person
- python基础--面向对象基础(类与对象、对象之间的交互和组合、面向对象的命名空间、面向对象的三大特性等)
python基础--面向对象 (1)面向过程VS面向对象 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. ...
- shell 输出json格式的内容
对于shell脚本的输出,如果要输出json格式的内容,我们可以借助python -m json.tool命令 比如 echo '{"name":"zhangsan&qu ...
- redis配置密码
一. 更改配置文件 找到requirepass这行, [soft@node5 redis-3.0.6]$ grep 'requirepass' redis.conf#requirepass fooba ...
- Mysql安装使用教程
一:简介 MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理.MySQL是开放源代码的,因此任何人都可以在Genera ...
- Numpy数组的函数
import numpy as np # 将 0~100 10等分 x = np.arange(0,100,10) # array([ 0, 10, 20, 30, 40, 50, 60, 70, 8 ...
- Python os.major() 方法
概述 os.major() 方法用于从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field).高佣联盟 www.cgewang.com 语法 major( ...