深度优先搜索算法详解及其两种实现
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))
接下来给出两种实现的示例代码:
一递归实现:
二栈的实现:
对两种方法的分析:
通过计算运行时间,你会发现使用栈实现会慢于使用递归的实现。
一.阅读本文的前置知识储备要求:
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.
}
对两种方法的分析:
通过计算运行时间,你会发现使用栈实现会慢于使用递归的实现。
相关文章推荐
- 搜狗百度360市值齐跌:搜索引擎们陷入集体焦虑?
- 本人即将筹备败家日志,敬请期待!
- IE:使用搜索助手
- C++深度优先搜索的实现方法
- 基于文本的搜索
- php实现搜索一维数组元素并删除二维数组对应元素的方法
- 使用Sphinx对索引进行搜索
- asp 多关键词搜索的简单实现方法
- C#使用foreach语句搜索数组元素的方法
- Javascript SHA-1:Secure Hash Algorithm
- JavaScript中数组的排序、乱序和搜索实现代码
- C#编程实现Excel文档中搜索文本内容的方法及思路
- sqlserver中在指定数据库的所有表的所有列中搜索给定的值
- 可以用来搜索当前页面内容的js代码
- 全文搜索和替换
- javascript搜索自动提示功能的实现第1/3页
- mysql 模糊搜索的方法介绍
- C#搜索文字在文件及文件夹中出现位置的方法
- 基于ASP.NET的lucene.net全文搜索实现步骤
- 做个自己站内搜索引擎