样图:

  

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++实现)的更多相关文章

  1. dfs和bfs算法

    1. 存储图的方式一般是有两种的:邻接表和邻接矩阵,一般存储链接矩阵的方式是比较简单的,也便于我们去实现这个临接矩阵,他也就是通俗的二维数组,我们平常用到的那种. 2. 这里我们主要记录和讲一下bfs ...

  2. 邻接表实现Dijkstra算法以及DFS与BFS算法

    //============================================================================ // Name : ListDijkstr ...

  3. 图的DFS与BFS遍历

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

  4. 图的遍历算法:DFS、BFS

    在图的基本算法中,最初需要接触的就是图的遍历算法,根据访问节点的顺序,可分为深度优先搜索(DFS)和广度优先搜索(BFS). DFS(深度优先搜索)算法 Depth-First-Search 深度优先 ...

  5. BFS与DFS常考算法整理

    BFS与DFS常考算法整理 Preface BFS(Breath-First Search,广度优先搜索)与DFS(Depth-First Search,深度优先搜索)是两种针对树与图数据结构的遍历或 ...

  6. 【数据结构与算法笔记04】对图搜索策略的一些思考(包括DFS和BFS)

    图搜索策略 这里的"图搜索策略"应该怎么理解呢? 首先,是"图搜索",所谓图无非就是由节点和边组成的,那么图搜索也就是将这个图中所有的节点和边都访问一遍. 其次 ...

  7. 图论中DFS与BFS的区别、用法、详解…

    DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...

  8. 图论中DFS与BFS的区别、用法、详解?

    DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...

  9. BFS算法(——模板习题与总结)

    首先需要说明的是BFS算法(广度优先算法)本质上也是枚举思想的一种体现,本身效率不是很高,当数据规模很小的时候还是可以一试的.其次很多人可能有这样的疑问,使用搜索算法的时候,到底选用DFS还是BFS, ...

随机推荐

  1. Linux(CentOS7)下如何配置多个JDK环境变量

    一.Linux版本 二.复制粘贴多个JDK出来,如下 cp -R jdk1.7.0_80/ jdk1.7.0_80-2 cp -R jdk1.7.0_80/ jdk1.7.0_80-3 三.配置多个J ...

  2. LeetCode算法题-1-bit and 2-bit Characters(Java实现)

    这是悦乐书的第302次更新,第321篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第170题(顺位题号是717).有两个特殊字符,第一个字符可以用一个比特0表示,第二个字 ...

  3. Web前端教程-HTML及标签的使用

    目录 1. HTML简介 1.1. HTML文档基本结构 2. 标签 2.1. 标签语法 1.2. 标签的属性和值 1.3. 常见的标签 1. 基础标签 2. 格式标签 3. 表单标签 4. 框架标签 ...

  4. VUE路由新页面打开的方法总结

    平常做单页面的场景比较多,所以大部分的业务是在同一个页面进行跳转.要通过VUE路由使用新页面打开且传递参数,可以采用以下两个方法: 1.router-link的target <router-li ...

  5. 宝塔服务器面板 部署 thinkphp5 坑

    thinkphp5 在宝塔服务器上部署,出现的问题: 1. File not found. 原因: 宝塔服务器默认不支持 pathinfo 的路径访问:需要在软件 - PHP - 管理里面,安装php ...

  6. 数据的偏度和峰度——df.skew()、df.kurt()

    我们一般会拿偏度和峰度来看数据的分布形态,而且一般会跟正态分布做比较,我们把正态分布的偏度和峰度都看做零.如果我们在实操中,算到偏度峰度不为0,即表明变量存在左偏右偏,或者是高顶平顶这么一说. 一.偏 ...

  7. 在混合开发框架模式中,简化客户端对Web API的频繁调用

    在混合开发框架模式中,有时候我们在处理树形节点的时候,需要很多关联的处理,可能需要结合用户配置信息,属性字典,以及表的字段分类等信息来展示一个结构树,那么在处理的时候就可能会频繁的对这些接口API进行 ...

  8. 随心测试_数据库_001<论数据的重要性>

    测试工作中,数据的重要性 软测工程师:作为综合运用多学科知识,保障软件质量的重要岗位.需要我们学以致用,在工作中不断学习提升.以下:软测人员必备_数据库核心技能学习点,供大家学习参考. Q1:什么是: ...

  9. django项目外部的脚本文件执行ORM操作,无需配置路由、视图启动django服务

    #一.将脚本路径添加到python的sys系统环境变量里 import sys # sys.path.append('c:/Users/Administrator/www/mymac') #第一种.绝 ...

  10. js 解决两值交换

    总结七种办法来交换a和b的变量值 交换变量值方案一 最最最简单的办法就是使用一个临时变量了 不过使用临时变量的方法实在是太low了 var t; t = a; a = b; b = t;   首先把a ...