ACM第二專題—搜索總結

概述:搜索分爲廣度優先搜索(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)
{
 if (sortedArray.Length == 0)
  return false;
 int start = 0;
 int end = sortedArray.Length - 1;       
 while (end >= start)
 {        
  int middle = (start + end) / 2;       
  if (sortedArray[middle] < number)       
   start = middle + 1;       
        else if (sortedArray[middle] > number)         
   end = middle - 1;        
  else
   return true;       
 }     
 return false;
}

 

然後是三分查找算法,時間複雜度O(3log3(n)):
static bool Find(int[] sortedArray, int number)
{
 if (sortedArray.Length == 0)
  return false;
 int start = 0;
 int end = sortedArray.Length - 1;
 while (end >= start)
 {
  int firstMiddle = (end - start) / 3 + start;
  int secondMiddle = end - (end - start) / 3;
  if (sortedArray[firstMiddle] > number)
   end = firstMiddle - 1;
  else if (sortedArray[secondMiddle] < number)
   start = secondMiddle + 1;
  else if (sortedArray[firstMiddle] != number && sortedArray[secondMiddle] != number)
  {
   end = secondMiddle - 1;
   start = firstMiddle + 1;
  }
  else
   return true;
 }
 return false;
}

對比可以發現,三分查找算法的時間複雜度要比二分查找算法的時間複雜度低,
但是實際上效率並沒有二分查找算法高,因此我們不能過於迷信一個算法的時間
複雜度。

總結:這一部分真心比較懵,就不多說了,還要好好在做些題。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章