概述:搜索分为广度优先搜索(BFS)和深度优先搜索(DFS)两类,前者用队列实现,后者用递归实现,后者用于列举所有可能情况,前者用于求最短路径。可以用二分搜索和三分搜索解决一些比较简单的搜索问题。
例题:
1.求连通块(DFS)
部分代码:
void
dfs(
int
r,
int
c,
int
id)
{
if
(r<
0
||r>=m||c<
0
||c>=n)
return
;
if
(idx[r][c]>
0
||tu[r][c]!=
'W'
)
return
;
idx[r][c]=id;
for
(
int
dr=-
1
; dr<=
1
; dr++)
for
(
int
dc=-
1
; dc<=
1
; dc++)
if
(dr!=
0
||dc!=
0
)
dfs(r+dr,c+dc,id);
}
用二重循环来找到当前格子相邻的八个格子,其实也可以用常量数组或者写八个DFS。
2.迷宫问题(BFS)
部分代码:
void bfs(int x,int y){
queue<int>q;//BFS搜索用队列实现
int d,u=0;
vis[x][y]=1; q.push(u); while(q.size()!=0){
u=q.front();//u和下面的临时变量v的作用是将二维图转化为一维数列存储
//该方法可以避开另建立结构体记录横坐标值和纵坐标值
//例如u=20即代表着第四行(从零算起)第零列的位置
//其中转化方法为下面两句
q.pop();//从队头拿出一个数
x=u/5; //除以列数,及得到第几行
y=u%5; //对列数取模,记得到列数
for(int i=0;i<4;i++){//上下左右查找
int nx = x+dir[i][0],
ny = y+dir[i][1];
if(nx>=0&&nx<=4&&ny>=0&&ny<=4&&!maze[nx][ny]&&!vis[nx][ny]){
int v = nx*5+ny;
q.push(v);//加入队尾
vis[nx][ny]=1;
dist[nx][ny]=dist[x][y]+1;
}
}
}
}
先bfs预处理能到达的点,不能到达终点则输出-1,否则dp。dp[i]-到达i点后要到达终点需要的步数的期望。对每一个能到达的点x0,假设其相邻的能到达的点有x1、x2、x3.则dp[x0]=1+dp[x1]/3+dp[x2]/3+dp[x3]。
3.二分查找和三分对比。
首先是二分查找法,时间复杂度O(2log2(n)):
static bool Find(int[] sortedArray, int number)
{
}
然后是三分查找算法,时间复杂度O(3log3(n)):
static bool Find(int[] sortedArray, int number)
{
}
对比可以发现,三分查找算法的时间复杂度要比二分查找算法的时间复杂度低,
但是实际上效率并没有二分查找算法高,因此我们不能过于迷信一个算法的时间
复杂度。
总结:这一部分真心比较懵,就不多说了,还要好好在做些题。