您的位置:首页 > 编程语言 > Go语言

深度优先搜索算法详解及其两种实现

2015-10-10 15:41 627 查看
深度优先搜索算法详解及其两种实现

一.阅读本文的前置知识储备要求

1. 知道如何存储一个图信息,两种,一个是二维数组01矩阵,另外一个是邻接表(一般是开一个vector的数组来做)。

2. 了解深度优先搜索的基本思想及算法内容。

二.算法思想

深度优先遍历图的方法(一种递归的定义)是,假定给定图G的初始状态是所有顶点均未被访问过,在G中任选一个顶点i作为遍历的初始点,则深度优先搜索递归调用包含以下操作:

(1)访问搜索到的未被访问的邻接点;

(2)将此顶点标记为已访问节点;

(3)搜索该顶点的未被访问的邻接点,若该邻接点存在,则从此邻接点开始进行同样的访问和搜索。

三.算法实现:

1. 使用栈来实现。相关算法实现总结为:

(1) 将初始节点压栈。

(2) While(栈非空){

(3) 取出栈顶点,暂时存储这个节点node_t信息。

(4) 访问该节点,并且标示已访问。

(5) 将栈顶元素出站。

(6) For(遍历node_t的相邻的未访问过的节点){

(7) 将其入栈。

}

}

注意事项:一定要先将该访问节点出栈后,再将其邻接的未访问的节点入栈。切记不要,之前我的经历,如果没有邻接点就出栈,否则就不出站,但是标记了该节点为访问节点的。

2. 使用递归来实现。相关算法实现总结为:

(1) DFS(初始节点)

(2) Function DFS(一个节点){

(3) 访问该节点,并且标示已访问。

(4) For(遍历该节点的相邻的未访问过的节点){

(5) DFS(这个邻接节点)。

}

}

四.算法运用

1.图的遍历。

2.判断图是否存在环路。

3.迷宫问题。

4.对某些问题进行穷举等等。。。。

五.算法实现举例:

题目大意:每次给出五个数和一个目标数,让你判断,利用其中的五个数判断能否通过简单的运算(加,减,乘,除)得到那个目标数。如果能则输出目标数,否则输出这五个数能凑到的小于目标数的最大的那个数。

备注:并不要求每个数都要用到,另外除法,必须要求能够进行整除,否则就不进行除法;例如,4/2则可以,1/7和9/4就不可以。

标准测试样例为:

输入为:五个数为:1, 2, 3, 7, 100;目标数为:573

输出:573 (因为:(((100-1)*2)-7)*3 = 573)

输入为:五个数为:67, 69, 58, 22, 2;目标数为:929

输出:573 (因为:923 = (22-(67-58))*(69+2))

接下来给出两种实现的示例代码:



一递归实现:




#include<iostream>


07.
#include<vector>


08.


09.
using
namespace
std;


10.
int
max_value,
target;


11.


12.
//depth
first search by recursion, not stack.


13.
bool
dfsearch(vector<
int
>
vec){


14.
//judge
whether to get the result and update the max value.


15.
int
len
= vec.size();


16.
for
(
int
i
= 0; i < len; i++){


17.
if
(vec[i]
== target)
return
true
;


18.
if
(vec[i]
> max_value && vec[i] < target)max_value = vec[i];


19.
}


20.
for
(
int
i
= 0; i < len; i++){


21.
for
(
int
j
= i + 1; j < len; j++){


22.
vector<
int
>
temp;


23.
for
(
int
k
= 0; k < len; k++)
if
(k
!= i && k != j)temp.push_back(vec[k]);


24.


25.
temp.push_back(vec[i]
+ vec[j]);


26.
if
(dfsearch(temp)
==
true
)
return
true
;


27.
temp.pop_back();


28.


29.
temp.push_back(vec[i]
- vec[j]);


30.
if
(dfsearch(temp)
==
true
)
return
true
;


31.
temp.pop_back();


32.


33.
temp.push_back(vec[j]
- vec[i]);


34.
if
(dfsearch(temp)
==
true
)
return
true
;


35.
temp.pop_back();


36.


37.
temp.push_back(vec[i]
* vec[j]);


38.
if
(dfsearch(temp)
==
true
)
return
true
;


39.
temp.pop_back();


40.


41.
if
(vec[i]
== 0 || vec[j] == 0)
continue
;


42.
int
max_t
= max(vec[i], vec[j]);


43.
int
min_t
= min(vec[i], vec[j]);


44.
if
(max_t%min_t
== 0){


45.
temp.push_back(max_t/min_t);


46.
if
(dfsearch(temp)
==
true
)
return
true
;


47.
temp.pop_back();


48.
}


49.
}


50.
}


51.
return
false
;


52.
}


53.


54.
int
main()
{


55.
int
num;


56.
cin
>> num;


57.
while
(num--)
{


58.
vector<
int
>
vec(5);


59.
for
(
int
i
= 0; i < 5; i++)cin >> vec[i];


60.
max_value
= -99999;


61.
cin
>> target;


62.
if
(dfsearch(vec)
==
true
)
cout << target << endl;


63.
else
cout
<< max_value << endl;


64.
}


65.
}





二栈的实现:


#include<iostream>


07.
#include<stack>


08.
#include<vector>


09.


10.
using
namespace
std;


11.


12.
int
max_value,
target;


13.


14.
int
main()
{


15.
int
num;


16.
cin
>> num;


17.
while
(num--)
{


18.
vector<
int
>
vec(5);


19.
for
(
int
i
= 0; i < 5; i++)cin >> vec[i];


20.
max_value
= -99999;


21.
cin
>> target;


22.


23.
stack<
vector<
int
>
> stk;


24.
bool
flag
=
false
;


25.
stk.push(vec);


26.
while
(!stk.empty())
{


27.
vector<
int
>
top = stk.top();


28.
int
len
= top.size();


29.
//the
terminal situation of this DFS.


30.
for
(
int
i
= 0; i < len; i++){


31.
if
(top[i]
== target){


32.
flag
=
true
;


33.
break
;


34.
}


35.
if
(top[i]
< target && top[i] > max_value)max_value = top[i];


36.
}


37.


38.
stk.pop();


39.


40.
for
(
int
i
= 0; i < len; i++){


41.
for
(
int
j
= i + 1; j < len; j++){


42.
vector<
int
>
temp;


43.
for
(
int
k
= 0; k < len; k++){


44.
if
(k
!= i && k != j)temp.push_back(top[k]);


45.
}


46.


47.
temp.push_back(top[i]
+ top[j]);


48.
stk.push(temp);


49.
temp.pop_back();


50.


51.
temp.push_back(top[i]
- top[j]);


52.
stk.push(temp);


53.
temp.pop_back();


54.


55.
temp.push_back(top[j]
- top[i]);


56.
stk.push(temp);


57.
temp.pop_back();


58.


59.
temp.push_back(top[i]
* top[j]);


60.
stk.push(temp);


61.
temp.pop_back();


62.


63.
if
(top[i]
== 0 || top[j] == 0)
continue
;


64.
int
max_t
= max(top[i], top[j]);


65.
int
min_t
= min(top[i], top[j]);


66.
if
(max_t%min_t
== 0){


67.
temp.push_back(max_t/min_t);


68.
stk.push(temp);


69.
temp.pop_back();


70.
}


71.
}


72.
}


73.


74.
}


75.
if
(flag)
cout << target << endl;


76.
else
cout
<< max_value << endl;


77.
}


78.
}

对两种方法的分析:

通过计算运行时间,你会发现使用栈实现会慢于使用递归的实现。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  algorithm 图论 搜索