算法学习-深度优先搜索

算法学习-深度优先搜索

1:总览深度优先搜索

深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法。它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念。

2:和广度优先搜索的对比

广度优先搜索(BFS)是按照一个树的层次来完成搜索的

  1. 缺点:当树的层次较深&&子节点过多的时候,消耗内存极其严重

    解释如下:

    ​ 假设一个节点衍生出来的相邻节点平均的个数是N个,那么当起点开始搜索的时候,队列有一个节点,当起点拿出来后,把它相邻的节点放进去,那么队列就有N个节点,当下一层的搜索中再加入元素到队列的时候,节点数达到了N^2,你可以想想,一旦N是一个比较大的数&&这个树的层次又比较深,那这个队列就得需要很大的内存空间了。

  2. 优点:可以寻找无权图的最短路~

深度优先搜索(DFS)在每次搜索的过程中每层仅仅只需要维护一个节点,内存消耗小。但是,刚刚也提到了深度优先搜索是沿着一条路找到黑的,需要找到所有的路径才可以确定最短路径。

  1. 缺点:难以寻找最优解
  2. 优点:内存消耗小

3:伪代码+具体例题

/**
 *DFS伪代码(递归实现)
 *@param n 当前开始搜索的节点
 *@param step 当前到达的深度,即任务完成量的一种度量
 */
void DFS(Node n,int step){
    //任务完成
    if(step == xxx){
        //do something 常常为输出/记录当前路径信息
    }
    for (Node nextNode in n){//遍历跟节点n相邻的节点nextNode
        //这个需要根据题意来确定下个节点是否可以访问
        if(nextNode可以访问){
            //进行一些压栈操作 往往是把当前节点变成不可以访问节点
            DFS(nextNode,step+1);
            //进行一些弹栈操作 往往是把当前节点变成可以访问节点
        }
    }
}

洛谷-八皇后递归问题

#include<iostream>
using namespace std;
bool ldiagonal[400];//左对角线 
bool rdiagonal[200];//右对角线 
bool cow[200];//列 
int cash[15];//缓存 
int n;//棋盘大小 
int ans;
/*
 *@param step 当前到达的深度,即任务完成量的一种度量
 *由于问题的特殊性,当前访问节点可以用step代替
 */
void solve(int step){
	if(step >= n){//任务是否完成的度量
		ans++;
		if(ans <= 3){
			for(int i = 0;i < n;i++){
				cout<<cash[i]<<" ";
			}
			cout<<endl;
		} 
		else{
			return;
		}
	} 
	//列 
	for(int j = 0;j < n;j++){//遍历当前行所有可以访问的列
        //查看列是否可以访问
		if(!cow[j]&&!rdiagonal[step + 1 + j]&&!ldiagonal[step + 1-j+n]){
			cash[step] = j + 1;
            //缓存操作,为了在任务完成时候,好记录/输出结果
			cow[j] = true;
			rdiagonal[step + 1+j] = true;
			ldiagonal[step + 1-j+n] = true;
            //上面三行为压栈操作,可以看出来是在把当前节点变成不可再次访问节点
			solve(step + 1);
            //递归操作
			cow[j] = false;
			rdiagonal[step + 1+j] = false;
			ldiagonal[step + 1-j+n] = false;
            //上面三行为弹栈操作
		}
	}
}
int main(){
	cin>>n;
	solve(0); 
	cout<<ans;
	return 0;
} 

最后,总结一下

深度优先搜索的算法需要你对递归有一定的认识,其中最重要的思想就是:抽象!

可以从DFS函数里边看到,DFS里边永远只处理当前状态节点n,而不去关注它的下一个状态。

它通过把DFS方法抽象加上使用递归,使整个逻辑就变得十分的清晰。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值