基本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, ...
随机推荐
- RESTful学习及应用
原文转自前端路上,转载请注明出处:http://refined-x.com/2017/09/22/RESTful学习及应用/ RESTful是什么 RESTful是一种API架构,符合REST设计原则 ...
- RecyclerView的Item的单击事件
RecyclerView 的每个Item的点击事件并没有像ListView一样封装在组件中,需要Item的单击事件时就需要自己去实现,在Adapter中为RecyclerView添加单击事件参考如下: ...
- .NET core2.0 发布至IIS中
.NET CORE和asp.net 发布时不太一样,ASP.NET Core不再是由IIS工作进程(w3wp.exe)托管,而是使用自托管Web服务器(Kestrel)运行,IIS则是作为反向代理的角 ...
- 修改DEDECMS文章标题长度,解决DEDECMS文章标题显示不全
dedecms系统使用过程中,常遇到输入的标题原本输入的字数跟保存成功后的数字长度不一样,这个是因为 织梦dedecms系统默认的文章标题字数限制是60,也就是只能输入30个汉字,超过的会自动截断删除 ...
- Graph图总结
将COMP20003中关于Graph的内容进行总结,内容来自COMP20003,中文术语并不准确,以英文为准. Graph G = {V, E} 顶Vertices V: can contain in ...
- java中的线程池原理
写的不错,https://www.cnblogs.com/dongguacai/p/6030187.html
- JSON获取地址
JSON获取地址一: https://github.com/stleary/JSON-java JSON获取地址二: http://genson.io/ JSON获取地址一: https://code ...
- Android 1.7 中不支持 lambda 表达式
Error:(129, 32) 错误: -source 1.7 中不支持 lambda 表达式 (请使用 -source 8 或更高版本以启用 lambda 表达式) lambda expressio ...
- https 自签名SSL证书
介绍 TLS或称传输层安全性,及其前身SSL(代表安全套接字层)是用于将正常流量包装在受保护的加密包装中的Web协议. 使用这种技术,服务器可以在服务器和客户端之间安全地发送流量,而不会被外部各方拦截 ...
- 在ConoHa上Centos7环境下源码安装部署LNMP
本文记录了从源码,在Centos 7上手动部署LNMP环境的过程,为了方便以后对nginx和mariadb进行升级,这里采用yum的方式进行安装. 1.建立运行网站和数据库的用户和组 groupadd ...