一、基础知识
- 链表:链表在内存中的存储可以不是一段连续的区域。
class ListNode {
int val;
ListNode next;
}
- 树:链表的一个延伸,有多个结点。不管是两个节点还是多个节点,树当中是有层级关系的。邻居的关系,这里也没有层级结构了,每个节点都是平等的。
class TreeNode {
int val;
List<TreeNode> children;
}
- 图:有向图,只能单向行驶,A→B,但是B不能到A;无向图,A↔B。
class GraphNode {
int val;
List<Integer> neighbors;
}
二、深度优先搜索的思想
深度优先搜索所遵循的搜索策略是尽可能“深”地搜索图,就像是在走迷宫,每次碰到一个岔路口,就选择一条路继续往下走,一直走到底,然后返回上一个路口走进另一条路,再次走到底,如此不断进行,知道找到目标或者搜索完所有的地方才退出搜索。
三、图示理解(图片来源于网络)
图中数字为其被搜索的顺序
三、框架
DFS(v)
{
if(v访问过)
return;
将v标记为访问过;
对v的下一个点u:DFS(u);
取消标记;
}
四、代码
题目:找出1-10有多少种排序方式
#include <iostream>
using namespace std;
int a[10];
itn book[10]={0};//标记数是否被使用,0为否,1为是
void DFS(int step)//到达第n+1的位置时,说明摆放完成
{
if(step==n+1)
{
for(int i=1;i<=n;i++)
cout<<a[i]<<' ';
return;//返回上一步
}
for(int i=1;i<n;i++)
{
if(book[i]==0)//判断该数是否已经摆放
{
a[step]=i;
book[i]=1;
DFS(step+1);//摆放下一个数
book[i]=0;//收回时消除标记
}
}
return ;
}
int main()
{
for(int i=1;i<=10;i++)
cin>>a[i];
DFS(1);
return 0;
}
五、例题
二叉树的最大深度(LeetCode 第 104 号问题)
class Solution {//不断地向下搜索,每次都返回最深的那个分支
public:
int maxDepth(TreeNode* root) {
if(root==NULL)
return 0;
int left1=maxDepth(root->left) ;
int right1=maxDepth(root->right);
return max(left1,right1)+1;
}
};
六、拓展
- 深度优先搜索不一定依靠递归来实现,还可以是函数栈来保存之前的函数。
- 一般的深度优先搜索是对之前的子问题的结果不进行保存的。
- 深度优先搜索的涵盖面很广。一方面,它比较好的和递归进行了结合;另一方面,很多其他算法的思想得到了体现。