資料結構與演算法基礎-02-二分查詢-實踐
阿新 • • 發佈:2018-11-10
演算法中查詢演算法和排序演算法可謂是最重要的兩種演算法,是其他高階演算法的基礎。在此係列文章中,將逐一學習和總結這兩種基礎演算法中常見的演算法實現。首先,第一種演算法——二分(折半)查詢的學習和練習。
1、概念
二分查詢,是逐次將查詢範圍折半,縮小搜尋的範圍,直到找到那個需要的結果。它是一種效率較高的查詢演算法,但是要使用它來完成查詢任務,有一個前提,那就是所要搜尋的範圍的資料結構是採用線性儲存結構的線性表,且它已經將資料排好序,常見的有陣列,下文以陣列為例進行說明。
2、演算法思想
每次取陣列中間位置的值與需要查詢的值比較,如果中間位置的值比需要查詢的值大,則在陣列前半部分迴圈這個查詢的過程;如果中間位置的值比需要查詢的值小,則在陣列後半部分迴圈這個查詢的過程。直到查詢到了為止,否則陣列中沒有需要查詢的值。
【注意】因為需要確定每次查詢的區間範圍,所以我們用pow表示區間的上界序號,low表示區間的下界序號,middle表示中間位置序號。
程式碼:
#include <iostream> #define NotFound -1 using namespace std; /* To get the length of the objective array[] */ int get_array_len(int array[] ){ int len =0; len =(sizeof(array) / sizeof(array[0])); if (len <= 0 ){ std::cout << "error"<< endl; return -1; } return len; } int binarySearch( int a[],int value) { int low = 0; int middle = 0; //定義區間下界並初始化為0,宣告中間位置變數middle int len = get_array_len(a); //計算陣列長度,返回長度len if (len == -1){ return -1; } int high = len; //上界high,初值為len if(a == NULL){ return NotFound; } //如果陣列為空,結束操作,返回-1 while(low <= high) { if (value > a[high]){ return NotFound; } middle = (low+high) /2; //為middle開始賦予初值 if(a[middle] == value) //先判斷middle所在處的值是不是需要查詢的值 return middle; //返回查詢到的目標值序號 else if(a[middle] > value) //若middle處的值大於需要查詢的值,則將搜尋範圍縮小到前半部分 high = middle - 1; else low = middle + 1; //若middle處的值小於需要查詢的值,則將搜尋範圍縮小到後半部分 } return NotFound; //若循壞結束,即high<low,說明需要查詢的值不存在,則返回x查詢失敗標誌-1 } /* check the input number */ int input_check (){ int num; cout<<"請輸入A/B中元素個數:"<<endl; cin>>num; bool flag = false; //判斷標誌位,如果r輸入數大於100000,標誌位置置false while (!flag){ //依題意,元素個數應小於1000000 if(num >1000000){ cout<<"元素個數應小於1000000,請重新輸入:"<<endl; cin>>num; flag = false; //大於100000false } else{ flag = true; } } return num; } int main() { int n = 0,m = 0; //從鍵盤錄入A,B兩個集合中的元素個數 n = input_check(); //從鍵盤讀入n並判斷其是否符合要求 m = input_check(); int *a = new int[n]; //建立動態陣列-A集合 int *b = new int[m]; //建立動態陣列-B集合 int *list = new int[m<=n? m: n]; //定義一個List來存放A,B中相同的元素 for(int i = 0;i<n;i++){ //給A中每個元素賦值 cout<<"A中元素值:"<<endl; cin>>a[i]; } int* p = NULL; p = list; for(int i=0;i<m;i++){ cout<<"B中元素值:"<<endl; cin>>b[i]; int result = binarySearch(a, b[i]); //對輸入的每個B陣列元素,在A中進行二分查詢,並將查詢結果返回至result if(result != -1) { //判斷返回結果,若結果不為-1,則說明查詢成功,即A中有此元素,將此元素加入list中 *p = a[result]; p++; cout<<result<<" "<<a[result]<<endl; } } int len_list = get_array_len(list); cout<<"A,B中相同的元素個數為:"<<len_list+1<<endl; for(int i = 0; i<= len_list; i++){ //將結果打印出來 cout<<list[i]<<endl; } delete [] a; delete [] b; return 0; }
3、總結:
二分查詢是一種效率較高的演算法,但是需要給定的數列是有序的。可以結合之後的排序演算法一起使用。