深度优先搜索(DFS)递归形式改为非递归形式
DFS将递归改为非递归这个方法的需求来自于一道三维积木组合的题目,还在苦苦调试中,暂且不提。
普通的认识对于递归向非递归的转化无非是使用栈,但是结合到深度搜索如何将栈很好利用,如何很好保存现场,都不是很轻松(自身感觉)。
网上大部分转化都是基于图的搜索进行,总是引出邻接点的概念,让人越看越迷,毕竟不是每个DFS都是图(不可否认都可以看成是图)。
在众多资料中看到了CSDN上的一个转化方法很新颖(结构之法,算法之道):http://blog.csdn.net/v_july_v/article/details/6111353。
最后一点结合图提出了用队列栈来进行转化,由于伪代码和图有关,而且用到标志什么的,并没有细看,但是这个思想倒是启发了我。于是我决定使用这个思想进行转化尝试。
全排列问题是一个典型的可利用DFS搜索出结果的题目,正巧我们学校的OJ上有这个题目的评测:http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1005
于是使用队列栈来进行全排列,核心思想是:
1.使用每一个队列表示深度搜索的同一层节点。
2.栈的关系表示的是父亲和儿子的关系,不同层节点,且底部栈表示父亲节点,上层栈表示儿子节点
整个非递归DFS过程如下:
1.初始化最底层栈
2.只要栈内还有队列继续循环(3-5):
3.将栈顶队列弹出:
4.判断栈顶队列是否为空,若为空,进行恢复现场操作,并且往回回溯,若不为空,将栈顶队列首元素出栈,为该元素生成下层节点,也为一个队列,然后将该元素作为已经遍历的一部分,记录到结果中。
5.判断生成的队列是否为空,为空,说明已经到了搜索最底层,可输出相应的解,若不为空,将此队列入栈。
这里有两个注意点:
1.恢复现场操作有两处:一处在放置结果的时候,一处为栈顶队列为空的时候
2.在第四步将栈顶队列首元素出栈之后,这个队列有可能为空,在这里不需要对这个队列进行和第5步类似的操作。因为有可能出现该节点为空,而儿子并不为空的情况。
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
int n;
int ans[];
int visited[]={};
typedef struct point{
int num;
}Point;
stack< queue<Point> > mainstack;
void DFS()
{ int cur=;
queue<Point> oneq;
for(int i=;i<=n;i++)
{
Point oneP;
oneP.num=i;
oneq.push(oneP);
}
mainstack.push(oneq);
while(!mainstack.empty())
{
queue<Point> twoq;
twoq=mainstack.top();mainstack.pop();
if(!twoq.empty())
{
Point twoP=twoq.front();twoq.pop();
int onenum=twoP.num;
visited[ans[cur]]=;//1.如果要修改则将当前置为可用
ans[cur]=onenum;
visited[onenum]=;
queue<Point> threeq;//该节点的子节点
for(int i=;i<=n;i++)
{
if(visited[i]==)
{
Point threep;
threep.num=i;//threep.flag=i;
threeq.push(threep);
}
}
//在这里直接加空判断,会出现本节点兄弟为空,儿子不为空的情况
mainstack.push(twoq);
//没有可扩展节点
if(threeq.empty())
{
for(int i=;i<=n;i++)
cout<<ans[i]<<" ";
cout<<endl;
}
else
{
mainstack.push(threeq);
cur++;
}
}
else
{
visited[ans[cur]]=;
ans[cur]=;//这里置0才能完全还原
cur--;
}
}
}
int main()
{
cin>>n;
DFS();
return ;
}
全排序非递归
至于到全排序查重的地方,应该还有可以优化的地方,暂且不提,此代码在XOJ上提交通过。
|
56 K
|
1072 MS
|
G++
|
Apple
|
深度优先搜索(DFS)递归形式改为非递归形式的更多相关文章
- Java递归调用改成非递归
在java语言中,使用递归调用时,如果过多的调用容易造成java.lang.StackOverflowError即栈溢出和程序执行过慢.这是一个潜在Bug和影响程序执行效率问题,需要谨慎使 ...
- 深度优先搜索 DFS 学习笔记
深度优先搜索 学习笔记 引入 深度优先搜索 DFS 是图论中最基础,最重要的算法之一.DFS 是一种盲目搜寻法,也就是在每个点 \(u\) 上,任选一条边 DFS,直到回溯到 \(u\) 时才选择别的 ...
- 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)
深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...
- 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)
需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...
- 深度优先搜索DFS和广度优先搜索BFS简单解析
转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ...
- 【算法入门】深度优先搜索(DFS)
深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解 ...
- 用深度优先搜索(DFS)解决多数图论问题
前言 本文大概是作者对图论大部分内容的分析和总结吧,\(\text{OI}\)和语文能力有限,且部分说明和推导可能有错误和不足,希望能指出. 创作本文是为了提供彼此学习交流的机会,也算是作者在忙碌的中 ...
- JS002. map( ) 和 filter( ) 的区别和实际应用场景(递归函数、深度优先搜索DFS)
在开发过程中难免会碰到省市区级联的操作,一般后端人员是不愿意将中文储存在数据库的. 由于应用页面较多,我们在通过区域Code写查字典函数时应该注意函数的 时间复杂度 / 空间复杂度. 如果用三层for ...
- 广度优先(bfs)和深度优先搜索(dfs)的应用实例
广度优先搜索应用举例:计算网络跳数 图结构在解决许多网络相关的问题时直到了重要的作用. 比如,用来确定在互联网中从一个结点到另一个结点(一个网络到其他网络的网关)的最佳路径.一种建模方法是采用无向图, ...
随机推荐
- HDU 2527
题目描述 HDU 2527 分析 霍夫曼编码的应用. 本题没有必要构造一棵完整的霍夫曼树.只需利用霍夫曼编码的原理,每次挑选频率最低的两个元素进行合并 ...
- iOS开发针对SQL语句的封装
1.使用依赖关系 a.需要添加libsqlite3.tbd 静态库. b.需要添加第三方框架 FMBD.MJExtension. 2. SQL语句类封装名DataBaseSqlTool 类方法介绍 ...
- Axure使用
(一) Axure rp的界面 1-主菜单工具栏 大部分类似office软件,不做详细解释,鼠标移到按钮上都有对应的提示. 2-主操作界面 绘制产品原型的操作区域,所有的用到的元件都拖到该区域. 3 ...
- C++对象的销毁
- Web性能优化方案
第一章 打开网站慢现状分析 在公司访问部署在IDC机房的VIP网站时会感觉很慢.是什么原因造成的?为了缩短页面的响应时间,改进我们的用户体验,我们需要知道用户的时间花在等待什么东西上. 可以跟踪一下我 ...
- DEDE里有个编码问题,不支持PHP5.4及以上版本!
公司新配置服务器,没有PHP环境,下载了个PHP5.5.25,配置完毕后,从另外一个服务器转移了一个DEDECMS做的网站,安装后,进入后台,恢复数据发现参数设置里的文本框,只要是中文信息,没有显示, ...
- Nginx阅读笔记
Nginx最常用的服务是提供反向代理,大家熟悉的最多的是正向代理,正向代理我们平常接触的最多,例如云梯,我们通过代理服务器作为客户端这边的中介接受请求,隐藏真实的客户,向服务器获取资源.而反向代理顾名 ...
- java 抽象类与接口的区别 整理
抽象类与接口的区别 抽象类 包含抽象方法的类就是抽象类,声明的语句:abstract class 必须是public protected 接口 对行为的抽象,声明语句:interface 抽象方法的修 ...
- @RequestParam
@MVC另外一个特性是其提取和解析请求参数的能力.让我们继续重构上面的方法,并在其中添加@RequestParam注解: @RequestMapping("/accounts/show&qu ...
- 告别IE给我们的web开发带来的困扰(使用chrome frame v8引擎)
茶爸爸个人微信:benyzhous,公众号:cha-baba欢迎骚扰 由于客户所有机器必须使用IE6浏览器,导致我们在开发项目过程中遇到非常多的样式与性能问题,在偶然的一次使用360软件管家搜索chr ...