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

来源:互联网 发布:男士乳液推荐知乎 编辑:程序博客网 时间:2024/06/05 01:10

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

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

      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) == truereturn true;
27.temp.pop_back();
28. 
29.temp.push_back(vec[i] - vec[j]);
30.if (dfsearch(temp) == truereturn true;
31.temp.pop_back();
32. 
33.temp.push_back(vec[j] - vec[i]);
34.if (dfsearch(temp) == truereturn true;
35.temp.pop_back();
36. 
37.temp.push_back(vec[i] * vec[j]);
38.if (dfsearch(temp) == truereturn 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) == truereturn 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.}
         对两种方法的分析:

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


 

0 0
原创粉丝点击