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步类似的操作。因为有可能出现该节点为空,而儿子并不为空的情况。

 1 #include<iostream>
 2 #include<stack>
 3 #include<queue>
 4 using namespace std;
 5 int n;
 6 int ans[12];
 7 int visited[12]={0};
 8 typedef struct point{
 9     int num;
10 }Point;
11 stack< queue<Point> > mainstack;
12 void DFS()
13 {
14
15     int cur=1;
16     queue<Point> oneq;
17     for(int i=1;i<=n;i++)
18     {
19         Point oneP;
20         oneP.num=i;
21         oneq.push(oneP);
22     }
23     mainstack.push(oneq);
24     while(!mainstack.empty())
25     {
26         queue<Point> twoq;
27         twoq=mainstack.top();mainstack.pop();
28         if(!twoq.empty())
29         {
30             Point twoP=twoq.front();twoq.pop();
31             int onenum=twoP.num;
32             visited[ans[cur]]=0;//1.如果要修改则将当前置为可用
33             ans[cur]=onenum;
34             visited[onenum]=1;
35             queue<Point> threeq;//该节点的子节点
36             for(int i=1;i<=n;i++)
37             {
38                 if(visited[i]==0)
39                 {
40                     Point threep;
41                     threep.num=i;//threep.flag=i;
42                     threeq.push(threep);
43                 }
44             }
45             //在这里直接加空判断,会出现本节点兄弟为空,儿子不为空的情况
46             mainstack.push(twoq);
47             //没有可扩展节点
48             if(threeq.empty())
49             {
50                 for(int i=1;i<=n;i++)
51                     cout<<ans[i]<<" ";
52                 cout<<endl;
53             }
54             else
55             {
56                 mainstack.push(threeq);
57                 cur++;
58             }
59         }
60         else
61         {
62             visited[ans[cur]]=0;
63             ans[cur]=0;//这里置0才能完全还原
64             cur--;
65         }
66     }
67 }
68 int main()
69 {
70     cin>>n;
71     DFS();
72     return 0;
73 }

全排序非递归

至于到全排序查重的地方,应该还有可以优化的地方,暂且不提,此代码在XOJ上提交通过。

1005
Accepted
56 K
1072 MS
G++
1406 B
Apple

转载于:https://www.cnblogs.com/holyprince/p/3482597.html

深度优先搜索(DFS)递归形式改为非递归形式相关推荐

  1. 【算法很美】深入递归 (下)深度优先搜索DFS问题

    深搜.回溯.剪枝 深度优先搜索DFS 2.1 无死角搜索I 数独游戏 部分和 水洼数目 2.2 回溯和剪枝 n皇后问题 素数环 困难的串 小结 一些使用 2.1 无死角搜索I 数独游戏 你一定听说过& ...

  2. 一文搞定深度优先搜索(DFS)与广度优先搜索(BFS)【含完整源码】

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  3. 深度优先搜索(DFS) 总结(算法+剪枝+优化总结)

    深度优先搜索(DFS) 总结(算法+剪枝+优化总结) 本文中会引用部分实例.文献资料来自不同的作者之手,由于资料整理比较困难,转载地址不在文中列举.如有侵权请联系我更换或删除!对于提供题解思路的各位大 ...

  4. 【算法入门】深度优先搜索(DFS)

    深度优先搜索(DFS) [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍 ...

  5. C++实现深度优先搜索DFS(附完整源码)

    C++实现深度优先搜索DFS C++实现深度优先搜索DFS完整源码(定义,实现,main函数测试) C++实现深度优先搜索DFS完整源码(定义,实现,main函数测试) #include <al ...

  6. C++用stack实现深度优先搜索DFS(附完整源码)

    C++用stack实现深度优先搜索DFS的实现 C++用stack实现深度优先搜索DFS的完整源码(定义,实现,main函数测试) C++用stack实现深度优先搜索DFS的完整源码(定义,实现,ma ...

  7. 快排 递归三种方式+非递归 --排序

    方法1–Hoare #include"Sort.h" void PrintArray(int* a, int n) {for (int i = 0; i < n; ++i){ ...

  8. 栈和深度优先搜索(DFS)

    与 BFS 类似,深度优先搜索(DFS)是用于在树/图中遍历/搜索的另一种重要算法.也可以在更抽象的场景中使用. 正如树的遍历中所提到的,我们可以用 DFS 进行 前序遍历,中序遍历 和 后序遍历.在 ...

  9. 【牛客 - 剑指offer】JZ12 矩阵中的路径 深度优先搜索DFS Java实现

    文章目录 剑指offer题解汇总 Java实现 本题链接 题目 题目主要信息 方案 深度优先搜索 剑指offer题解汇总 Java实现 https://blog.csdn.net/guliguligu ...

最新文章

  1. Linux那些事儿之我是Sysfs(6)文件系统
  2. Xcode插件,模板安装
  3. Luogu P5469 [NOI2019]机器人 (DP、多项式)
  4. Tomcat关闭失败,SEVERE: Could not contact localhost:8005. Tomcat may not be running.
  5. 隐藏windows任务栏中的窗口显示
  6. KlayGE 4.4中渲染的改进(三):高质量无限地形
  7. 美国街头出现怪异无人车:3个激光雷达垂直叠放
  8. Service服务Android
  9. Android 开发性能优化
  10. Android 的 Recovery 模式分析
  11. asp.net oracle连接数据库,通过ASP.NET连接Oracle数据库实例教程
  12. Shell 脚本常用命令
  13. 客户关系管理系统(Customer Relationship Management)
  14. js 判断是否等于0不要用!
  15. 惠州东江威立雅的全方位文件安全管理
  16. 2019流量获取方式大盘点(实用技巧+PDF下载)
  17. 35岁前多用利弊分析,35岁后要有“安全边际”
  18. 酷点 CoolDock 0.75 发布:内存占用优化 修正多个问题
  19. Docker 官网文档翻译汇总
  20. webwork的 ww:radio 无法设置选择项显示默认项的问题

热门文章

  1. Mysql用户管理以及权限管理
  2. 前端开发教程:使用 CSS3 Transforms 构建圆形导航
  3. Windows下电脑硬盘的日常维护
  4. keycode值列表
  5. [原创]利用WM_COPYDATA实现进程间通信
  6. 另类windows与ubuntu共享实现
  7. [python] raw string,反斜杠\,re Lib
  8. 20.Azure备份Azure上的虚拟机(中)
  9. phpexcel 导出到xls文件的时候出现乱码解决
  10. 推荐JS插件:imagesLoaded,监测图片加载情况并提供相应的事件(加载成功/失败)...