深度搜索应用之黑白图像(非递归)

深度搜索应用之黑白图像(非递归)

前言:

  使用深度搜索,有两个方法:递归,栈。本质是栈。

  递归有一个缺陷,栈溢出。栈有一个缺陷,程序相对递归更复杂。

练习题:

  输入一个n*n的黑白图像(1表示黑色,0表示白色),任务是统计其中八连块的个数。如果两个黑格子有公共边或者公共顶点,就说它们属于同一个八连块。(题意是让求连在一起的块有几个,图见书本)

 

使用递归求解:点这里

使用栈求解:


 1 #include <iostream>
2 #include <memory.h>
3 #include <stack>
4 using namespace std;
5 const int MAXN=8;
6
7 typedef struct
8 {
9 int x;
10 int y;
11 } node;
12
13 stack<node> stack_temp;
14 node node_temp;
15 void push_value(int x,int y)
16 {
17 node_temp.x=x;
18 node_temp.y=y;
19 stack_temp.push(node_temp);
20 }
21
22 int mat[MAXN][MAXN]= {0,0,0,0,0,0,0,0,
23 0,1,0,0,1,0,0,0,
24 0,0,0,1,0,1,0,0,
25 0,0,0,0,0,0,0,0,
26 0,1,1,0,0,0,0,0,
27 0,1,1,1,0,0,0,0,
28 0,0,1,0,1,0,0,0,
29 0,0,0,0,0,0,0,0
30 },vist[MAXN][MAXN]= {0};
31
32 void dfs(int x,int y)
33 {
34 push_value(x,y);
35 vist[x][y]=1;
36 bool flag_break=false;
37 bool flag_for_over=false;
38 while(!stack_temp.empty())
39 {
40 int temp_x=stack_temp.top().x,temp_y=stack_temp.top().y;
41
42 /**< 对周围的8个结点进行遍历 */
43 for(int i=temp_x-1,last_x = temp_x+1; i<=last_x; ++i)
44 {
45 for(int j=temp_y-1,last_y = temp_y+1; j<=last_y; ++j)
46 {
47 if(mat[i][j]&&!vist[i][j])
48 {
49 cout<<"("<<i<<","<<j<<")"<<endl;
50 vist[i][j]=1;
51 push_value(i,j);
52 flag_break=true;
53 break;
54 }
55 }
56 /**< 用于标志一个有效结点,方便对下周围的结点进行遍历 */
57 if(flag_break)
58 {
59 flag_break=false;
60 break;
61 }
62
63 /**< 用于标志一个for循环是否结束,用于判断出栈的标志 */
64 if(i>=last_x)
65 {
66 flag_for_over=true;

67 break;
68 }
69 }
70
71 /**< 若一个循环结束,则踢出一个结点 */
72 if(flag_for_over)
73 {
74 stack_temp.pop();
75 flag_for_over=false;
76 }
77 }
78 return ;
79 }
80
81 int main()
82 {
83 int count_=0;
84 memset(vist,0,sizeof(vist));
85 for(int i=1; i<=6; ++i)
86 {
87 for(int j=1; j<=6; ++j)
88 {
89 if(mat[i][j] && !vist[i][j])
90 {
91 ++count_;
92 dfs(i,j);
93 }
94 }
95 }
96 cout<<count_<<endl;
97 return 0;
98 }

参考资料:点这里

时间: 2024-11-10 08:16:37

深度搜索应用之黑白图像(非递归)的相关文章

图论 深度优先搜索 广度优先搜索的非递归实现

深度优先遍历 1.深度优先遍历的递归定义 假设给定图G的初态是所有顶点均未曾访问过.在G中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下:首先访问出发点v,并将其标记为已访问过:然后依次从v出发搜索v的每个邻接点w.若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止.若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止. 图的深度优先遍历类似于树的

2013-03-17---二叉树递归,非递归实现(附代码)深度,叶子节点数量,逐行打印二叉树

昨天晚上没有发文章,说来话长啊,昨天不知道是csdn的问题,还是我的问题,我访问了半天,访问不上网站啊,后来12点多了,就睡了.上一篇文章说到了二叉树的先序,中序,后序遍历问题,这次还是说的简单的一点,说计算二叉树的深度,和叶子节点数量 int ceng(Node *pRoot) //计算层数,递归实现 { int left = 0; int right = 0; int res = 0; if (pRoot == NULL) { return 0; } if (pRoot->pLeft !=

【数据结构】搜索二叉树的(递归与非递归)实现,包括:增Insert,删Remove,查Find

搜索二叉树,是二叉树一种特殊的结构. 特点: (1)每个节点都有一个关键码,并且关键码不重复. (2)左子树上的每个节点的关键码都小于根节点的关键码. (3)右子树上的每个节点的关键码都大于根节点的关键码. (4)左右子树都是搜索二叉树. 下面,为方便大家理解,我举例画一个搜索二叉树,如下: 代码见下: #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; //搜索二叉树的节点结构 template&

图的深度优先搜索 递归和非递归实现 c++版本

本文参考了李春葆版本的数据结构上机指导,但是原版是c代码, 本文用了c++实现,并且修复了深度优先搜索非递归的一个bug. graph.cpp文件: #include "graph.h" #include <queue> #include <stack> int visited[MAXV ]; MGraph ::MGraph(int A[100][10], int nn , int ee) { e= ee ; n= nn ; for (int i=0;i<

二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现

一.基本概念 每个结点最多有两棵子树,左子树和右子树,次序不可以颠倒. 性质: 1.非空二叉树的第n层上至多有2^(n-1)个元素. 2.深度为h的二叉树至多有2^h-1个结点. 满二叉树:所有终端都在同一层次,且非终端结点的度数为2. 在满二叉树中若其深度为h,则其所包含的结点数必为2^h-1. 完全二叉树:除了最大的层次即成为一颗满二叉树且层次最大那层所有的结点均向左靠齐,即集中在左面的位置上,不能有空位置. 对于完全二叉树,设一个结点为i则其父节点为i/2,2i为左子节点,2i+1为右子节

【数据结构与算法】二叉树深度遍历(非递归)

据说这个笔试面试的时候非常easy考到,所以写到这里. 图示 代码实现 /** * 源代码名称:TreeIteratorNoRecursion.java * 日期:2014-08-23 * 程序功能:二叉树深度遍历(非递归) * 版权:[email protected] * 作者:A2BGeek */ import java.util.Stack; public class TreeIteratorNoRecursion { class TreeNode<T> { private T mNod

JavaScript 深度遍历对象的两种方式,递归与非递归

递归遍历: 基本问题: 当前属性值不为对象时,打印键和值 递归过程:当前属性值为对象时,打印键,继续递归 var o = { a: { b: { c: { d: { e: { f: 1, g:{ h:2 } } } } } } }; function printObjRec(obj) { for (var prop in obj) { if (typeof (obj[prop]) === "object") { console.log(prop); getProp(obj[prop])

深度卷积网络CNN与图像语义分割

转载请注明出处: http://xiahouzuoxin.github.io/notes/ 级别1:DL快速上手 级别2:从Caffe着手实践 级别3:读paper,网络Train起来 级别3:Demo跑起来 读一些源码玩玩 熟悉Caffe接口,写Demo这是硬功夫 分析各层Layer输出特征 级别4:何不自己搭个CNN玩玩 级别5:加速吧,GPU编程 关于语义分割的一些其它工作 说好的要笔耕不缀,这开始一边实习一边找工作,还摊上了自己的一点私事困扰,这几个月的东西都没来得及总结一下.这就来记录

非递归实现二叉查找树

之前在学习二叉查找树时按照递归方式实现了二叉查找树: http://www.cnblogs.com/elvalad/p/4129650.html 在实际应用中由于递归的深度和性能等问题会要求使用非递归方式实现二叉查找树的search操作,这里用循环的方式实现put,get,min和max操作.二叉查找树的非递归实现主要依赖二叉树的特点根节点的左子树的key都比根节点的key小,右子树的key都比根节点的key大这一特点,并通过left和right两个指针进行左子树或右子树的遍历,找到相应的key