演算法-遞迴與分治政策-二分搜尋
給定已按非升序排好的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);
}