1. 程式人生 > 其它 >演算法-遞迴與分治政策-二分搜尋

演算法-遞迴與分治政策-二分搜尋

7-1 二分搜尋(分治法)

給定已按非升序排好的n個元素a[0:n-1],在這n個元素中找出一特定元素x。要求演算法在最壞情況下的時間效率為 O(logn)。

輸入格式:

第一行為n值(n<=1000)和x值;第二行為n個整數。

輸出格式:

如果找到x,輸出x的下標;否則,輸出-1

輸入樣例:

5 2
5 4 3 2 1
(結尾無空行)

輸出樣例:

3
(結尾無空行)

/*資料按照降序排列,要求用二分法查詢元素X
第一行輸入n,x的值
第二行輸入n個整數
n個整數用什麼來儲存--陣列a[]
設定兩個指標,left和right
*/
/*知識回顧
二分查詢(折半查詢):是一種效率較高的查詢方法,但要求線性表必須使用順序儲存結構,且表中元素按照關鍵字有序排列。


時間複雜度O(log2n).
侷限性:
1.基於順序表儲存結構
2.適合一次排序,多次查詢。因此針對有序且靜態資料。那,在動態資料集合中,如何快速查詢資料?考慮樹查詢
3. 資料量小,不需要二分
4. 資料量太大也不行

非遞迴演算法
1. 設表長為n,low、high和mid分別指向待查元素所在區間的上界、下界和中點, k為給定值。
2. 初始時,令:low = 1, high = n,
mid = (low+high)/2
3. 重複以下操作,直至low>high(查詢失敗):
1)若 k == R[mid].key,查詢成功
2)若 k < R[mid].key,則high = mid-1


3)若 k > R[mid].key,則low = mid+1

int Search_Bin(SSTable ST, KeyType key)
{ //若找到,則函式值為該元素在表中的位置,否則為0
  low = 1; high = ST.length;
  while(low <= high)

  {
    mid = (low+high) / 2;
    if(key == ST.R[mid].key) return mid;
     else if(key < ST.R[mid].key) high = mid-1;

//前一子表查詢
    else low = mid + 1; //後一子表查詢
  }
  return 0;                   //表中不存在待查元素
}

遞迴演算法
int Search_Bin(SSTable ST, keyType key, int low,int high)
{
  if(low>high) return 0;    //查詢不到時返回0
  mid = (low+high) / 2;
  if(key==ST.elem[mid].key) return mid;
  else if(key<ST.elem[mid].key)
  ……..           //遞迴
  else …….          //遞迴
}

*/

#include<iostream>
using namespace std;


int bsearch(int x,int a[],int left,int right)
{
  if(left>right) //注意終止條件!沒有數
    return -1;
  int mid=(left+right)/2;
  if(x==a[mid])
    return mid;
  if(x<a[mid])
    return bsearch(x,a,mid+1,right);
  else
    return bsearch(x,a,left,mid-1);
}
/**
5 4 3 2 1
left mid right
x = 2 < a[mid]

**/
int main()
{
  int n,x;
  int a[10];
  cin >> n >> x;
  for(int i=0;i<n;i++)
  {
    cin >> a[i];
  }
  cout << bsearch(x,a,0,n-1);
}