基本DFS与BFS算法(C++实现)
样图:

DFS:深度优先搜索,是一个不断探查和回溯的过程,每探查一步就将该步访问位置为true,接着在该点所有邻接节点中,找出尚未访问过的一个,将其作为下个探查的目标,接着对这个目标进行相同的操作,直到回到最初的节点,此时图中所有节点都访问过了。
BFS:广度优先搜索,是一个逐层遍历的过程,每探查一步就将该步访问位置为true,接着在该点所有邻接节点中,找出尚未访问过的一个,将其作为下个探查的目标,接着还是对该节点(而不是所选择的目标)剩下的未访问的点选择一个,作为下一个探查的目标,直到没有邻接点为止。这些探测过的点存放于一个队列中,当该节点没有邻接节点时,取出队首的点进行相同的操作,直到队列为空,此时图中所有节点都访问过了。
实现代码(邻接矩阵法和邻接表法):
邻接矩阵法:(时间复杂度n^2),n代表顶点
#include<iostream>
#include<queue>
#define maxValue 100
using namespace std;
template<class E>
class Graph{//图的邻接矩阵表示(无向图)
public:
Graph(int n){
numV=n;
vlist=new int[n];
visited=new bool[n];
edge=new E*[n];
for(int i=;i<n;i++){
vlist[i]=i;
edge[i]=new E[n];
visited[i]=false;
}
visited[]=true;
for(int i=;i<n;i++){
for(int j=;j<n;j++){
edge[i][j]=(i==j)?:maxValue;
}
}
}
~Graph(){
delete []vlist;
delete []edge;
delete []visited;
}
int getFirst(int v){//获取顶点V的第一个邻接点
for(int col=;col<numV;col++)
if(edge[v][col]>&&edge[v][col]<maxValue)
return col;
return -;
}
int getNext(int v,int w){//获取顶点V的某个邻接点w的下一个 邻接点
for(int col=w+;col<numV;col++)
if(edge[v][col]>&&edge[v][col]<maxValue)
return col;
return -;
}
bool removeV(int v){//删除一个定点上的所有关联边
for(int i=;i<numV;i++){
if(i!=v){
edge[v][i]=maxValue;
edge[i][v]=maxValue;
}
}
}
bool insertE(int v1,int v2,E cost){//插入边V1,V2
edge[v1][v2]=edge[v2][v1]=cost;
}
bool removeE(int v1,int v2){//删除边V1,V2
edge[v1][v2]=edge[v2][v1]=maxValue;
}
E getW(int v1,int v2){//返回边(v1,v2)上的权值
return edge[v1][v2];
}
void DFS(int v){//深度优先搜索
cout<<(char)(vlist[v]+)<<" ";//打印节点
visited[v]=true;//标记该节点被访问过
int w=getFirst(v);//w为节点v的第一个邻接节点
while(w!=-){//v仍有临接节点未访问完
if(visited[w]==false) DFS(w);//如果w未被访问,对w进行新一轮DFS
w=getNext(v,w);//w重新设置成v的下一个临接节点
}
}
void BFS(int v){//广度优先搜索
cout<<(char)(vlist[v]+)<<" ";//打印节点
visited[v]=true;//标记该节点被访问过
queue<int> q;//辅助队列q
q.push(v);//将节点v入队
while(!q.empty()){//队列不为空
int v=q.front();//v为队首元素
q.pop();//v出队
int w=getFirst(v);//w为节点v的第一个邻接节点
while(w!=-){//v仍有临接节点未访问完
if(visited[w]==false){//如果w未被访问,打印节点, 标记该节点被访问过 ,并将该节点入队
cout<<(char)(vlist[w]+)<<" ";
visited[w]=true;
q.push(w);
}
w=getNext(v,w);//w重新设置成v的下一个临接节点
}
}
}
void print(){//打印图
for(int i=;i<numV;i++){
for(int j=;j<numV;j++){
if(edge[i][j]==maxValue)
cout<<"#"<<" ";
else
cout<<edge[i][j]<<" ";
}
cout<<endl;
}
}
private:
int *vlist;
bool *visited;
E **edge;
int numV; };
//1-9分别对应A-I
int main(){
Graph<int> *g=new Graph<int>();
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
// g->DFS(1);//利用注释来回切换
g->BFS();
delete g;
return ;
}
邻接表法:(时间复杂度n+e),e代表边
#include<iostream>
#include<queue>
#define maxValue 100
using namespace std;
template<class E>
struct e{
int v;
e<E> *link;
E cost;
e(int _v,E w,e *l=NULL){
v=_v;
cost=w;
link=l;
}
};
template<class E>
struct V{
char data;
e<E> *link;
V(char d,e<E> *l=NULL){
data=d;
link=l;
}
};
template<class E>
class Graph{
public:
Graph(int n){
numV=n;
vlist=new V<E>*[n];
visited=new bool[n];
for(int i=;i<n;i++){
vlist[i]=new V<E>(i+);
visited[i]=false;
}
visited[]=true;
}
~Graph(){
delete[] vlist;
}
int getFirst(int v){
e<E> *p=vlist[v]->link;
if(p!=NULL)
return p->v;
return -;
}
int getNext(int v,int w){
e<E> *p=vlist[v]->link;
while(p!=NULL&&p->v!=w){
p=p->link;
}
if(p!=NULL&&p->link!=NULL){
return p->link->v;
}
return -;
}
E getW(int v1,int v2){
e<E> *p=vlist[v1]->link;
while(p!=NULL&&p->v!=v2){
p=p->link;
}
if(p!=NULL){
return p->cost;
}
return ;
}
bool removeV(int v){
e<E> *p,*q;
int k;
while(vlist[v]->link!=NULL){
e<E> *m=NULL;
p=vlist[v]->link;
k=p->v;
q=vlist[k]->link;
while(q!=NULL&&q->v!=v){
m=q;q=q->link;
}
if(q!=NULL){
if(m==NULL) vlist[k]->link=q->link;
else m->link=q->link;
delete q;
}
vlist[v]->link=p->link;
delete p;
}
return true;
}
bool insertE(int v1,int v2,int w){
e<E> *p=vlist[v1]->link;
e<E> *q;
bool isIn=false;
while(p!=NULL){
if(p->v==v2){
p->cost=w;
isIn=true;
break;
}
p=p->link;
}
if(isIn){
q=vlist[v2]->link;
while(q!=NULL){
if(q->v==v1){
q->cost=w;
break;
}
q=q->link;
}
return true;
}else{
p=new e<E>(v2,w,vlist[v1]->link);
vlist[v1]->link=p;
q=new e<E>(v1,w,vlist[v2]->link);
vlist[v2]->link=q;
return true;
}
return false;
}
bool removeE(int v1,int v2){
e<E> *p=vlist[v1]->link;
e<E> *q=NULL;
while(p!=NULL){
if(p->v==v2)
break;
else{
q=p;
p=p->link;
}
}
if(p!=NULL){
if(p==vlist[v1]->link) vlist[v1]->link=p->link;
else{
q->link=p->link;
delete p;
}
}else{
return false;
}
p=vlist[v2]->link;
q=NULL;
while(p!=NULL){
if(p->v==v1)
break;
else{
q=p;
p=p->link;
}
}
if(p!=NULL){
if(p==vlist[v2]->link) vlist[v2]->link=p->link;
else{
q->link=p->link;
delete p;
}
}else{
return false;
}
}
void DFS(int v){
cout<<vlist[v]->data<<" ";
visited[v]=true;
int w=getFirst(v);
while(w!=-){
if(visited[w]==false) DFS(w);
w=getNext(v,w);
}
}
void BFS(int v){
cout<<vlist[v]->data<<" ";
visited[v]=true;
queue<int> q;
q.push(v);
while(!q.empty()){
int v=q.front();
q.pop();
int w=getFirst(v);
while(w!=-){
if(visited[w]==false){
cout<<vlist[w]->data<<" ";
visited[w]=true;
q.push(w);
}
w=getNext(v,w);
}
}
}
void print(){//打印邻接表
for(int i=;i<numV;i++){
cout<<vlist[i]->data<<"->";
e<E> *p=vlist[i]->link;
while(p!=NULL){
cout<<p->v<<" "<<p->cost<<"->";
p=p->link;
}
cout<<"^"<<endl;
}
}
private:
V<E> **vlist;
bool *visited;
int numV;
};
int main(){
Graph<int> *g=new Graph<int>();
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
g->insertE(,,);
// g->DFS(1);
g->BFS();
delete g;
return ;
}
基本DFS与BFS算法(C++实现)的更多相关文章
- dfs和bfs算法
1. 存储图的方式一般是有两种的:邻接表和邻接矩阵,一般存储链接矩阵的方式是比较简单的,也便于我们去实现这个临接矩阵,他也就是通俗的二维数组,我们平常用到的那种. 2. 这里我们主要记录和讲一下bfs ...
- 邻接表实现Dijkstra算法以及DFS与BFS算法
//============================================================================ // Name : ListDijkstr ...
- 图的DFS与BFS遍历
一.图的基本概念 1.邻接点:对于无向图无v1 与v2之间有一条弧,则称v1与v2互为邻接点:对于有向图而言<v1,v2>代表有一条从v1到v2的弧,则称v2为v1的邻接点. 2.度:就是 ...
- 图的遍历算法:DFS、BFS
在图的基本算法中,最初需要接触的就是图的遍历算法,根据访问节点的顺序,可分为深度优先搜索(DFS)和广度优先搜索(BFS). DFS(深度优先搜索)算法 Depth-First-Search 深度优先 ...
- BFS与DFS常考算法整理
BFS与DFS常考算法整理 Preface BFS(Breath-First Search,广度优先搜索)与DFS(Depth-First Search,深度优先搜索)是两种针对树与图数据结构的遍历或 ...
- 【数据结构与算法笔记04】对图搜索策略的一些思考(包括DFS和BFS)
图搜索策略 这里的"图搜索策略"应该怎么理解呢? 首先,是"图搜索",所谓图无非就是由节点和边组成的,那么图搜索也就是将这个图中所有的节点和边都访问一遍. 其次 ...
- 图论中DFS与BFS的区别、用法、详解…
DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...
- 图论中DFS与BFS的区别、用法、详解?
DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...
- BFS算法(——模板习题与总结)
首先需要说明的是BFS算法(广度优先算法)本质上也是枚举思想的一种体现,本身效率不是很高,当数据规模很小的时候还是可以一试的.其次很多人可能有这样的疑问,使用搜索算法的时候,到底选用DFS还是BFS, ...
随机推荐
- Docker: Jenkins里的pipeline编写基本技巧
Jenkins里,先新建一个pipeline项目 Pipeline Syntax 在Sample Step里选择需要的插件,如果不存在,就去系统管理,插件管理里,进行安装. 如果源码管理工具用的是gi ...
- flask-cache报错No module named 'flask.ext;解决方案
找到flask-cache包中的jinja2ext.py,将from flask.ext.cache import make_template_fragment_key改为from flask_cac ...
- shell编程企业级实战(2)
Vim配置文件.vimrc vim配置文件 if 条件语句 if是最常见的条件判断语句 例1:如果不存在/backup目录就创建. [root@web-01 /server/tools]# vim 0 ...
- SQL 游标的使用
适用场景:对查询出的结果集遍历,作用类似于其他语言的列表循环语句. 相关语法: --定义游标 DECLARE cr CURSOR FOR( SELECT Cust_ID ,Cust_Name ,IDC ...
- MyCP(课下作业)
一.作业要求 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.bin 用来把文本文件(内 ...
- Facebook 广告投放相关概念简介(1)
本文不涉及具体代码实现,仅对开发API的前置内容做简单介绍,想参考代码请绕行! 广告主(广告管理工具) ·需要推广自己的应用.网站.主页,所以有了广告管理工具 . ·一个广告主仅可拥有一个广告账户(可 ...
- GUI编程实战
1.拆分窗格:JSplistPane package swing; /** * swing 实战 */ import java.awt.*; import javax.swing.*; public ...
- 菜鸟学python之大数据的初认识
这次作业的要求来自于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2639 1.这些分析所采用数据来源是什么? 国家数据库:中国铁路 ...
- Photoshop给河边婚片加上唯美的霞光
<点小图查看大图> 最终效果 1.打开原图素材大图,按Ctrl + Alt + 2 调出高光选区,按Ctrl + Shift + I 反选得到暗部选区,然后创建曲线调整图层,对RGB.红. ...
- foreman容器化部署
一.前言 最近公司要求对一批GPU服务器安装操作系统,之前同事一直采用cobbler安装系统,一旦服务器设置为pxe优先启动,会出现重复安装系统的问题,并且如果线上服务器忘记修改第一启动项为硬盘启动, ...