12、【演算法】查詢演算法總結
阿新 • • 發佈:2018-11-04
一、順序查詢
1、定義
順序查詢屬於無序查詢,從資料結構的一端開始,順序掃描,依次將掃描到的節點關鍵字與給定值K相比,若相等,則表示查詢成功,若掃描結束,仍未找到關鍵字與給定值K相等,則表示查詢失敗。
時間複雜度分析
查詢成功時:平均查詢長度為(N+1)/2
查詢失敗時:需要比較N+1次
因此,順序查詢的時間複雜度為O(N)
2、 實現(C++)
int search(int *arr, int K)
{
int len = sizeof(arr)/sizeof(arr[0]);//計算陣列大小
for(int i = 0 ; i < len; i++)
{
if(k == arr[i])
return i;
}
return 0;
}
二、二分查詢
1、定義
也稱折半查詢,元素必須是有序的,如果是無序的,則要先進性排序操作。
時間複雜度分析
最壞的情況,關鍵字比較次數為:log2(N+1),且期望事件複雜度為O(log2N)
2、實現
(C++ 非遞迴)
int binarySearch(int *arr, int value)
{
int left, high, mid;
int len;
len = sizeof(arr)/sizeof(arr[0]);//獲取陣列長度
left = 0;
high = len - 1;
while(left <= high)
{
mid = (left + high)/2;
if(arr[mid] == value)
return mid;
if(arr[mid] < value)
left = mid + 1;
if(arr[mid] > value)
high = mid - 1;
}
return -1;
}
(C++ 遞迴)
int binarySearch(int *arr, int value, int low, int high)
{
int mid = (low + high)/2;
if(arr[mid] == value)
return mid;
if(arr[mid] > value)
return binarySearch(arr, value, low, mid - 1);
if(arr[mid] < value)
return binarySearch(arr, value, mid+1, high);
}
三、插值查詢
1、定義
插值查詢是對摺半查詢的優化,本質上是對查詢點進行改進:mid = low + ((Key - arr[low])/(arr[high] - arr[low]))*(high - low);
也就是將比例引數1/2改進為自適應的。
適用於表長較大,而關鍵字分佈又比較均勻的查詢表。反之,如果表中分佈非常不均勻,那麼插值查詢未必是很合適的選擇。
時間複雜度分析
查詢成功或者失敗的時間複雜度均為O(log2(log2N))
2、實現(C++ 遞迴)
int insertionSearch(int *arr, int value, int low, int high)
{
int mid = low + ((value - arr[low])/(arr[high] - arr[low]))*(high - low);
if(arr[mid] == value)
return mid;
if(arr[mid] > value)
insertionSearch(arr, value, low, mid-1);
if(arr[mid] < value)
insertionSearch(arr, value, mid+1, high);
}
4、斐波那契查詢
1、定義
黃金分割比的值約1:0.618或者1.618:1
斐波那契數列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….,其前後兩個值的比值越來越接近0.618,利用這個特性,就可以將黃金分割比運用到查詢技術中。
斐波那契查詢演算法同樣是二分查詢的一種改進。通過運用環境分割比的概念在數列中選擇查詢點進行查詢,提高查詢效率。斐波那契查詢也屬於一種有序查詢演算法。
時間複雜度分析
最壞的情況下:時間複雜度為O(log2N),且期望複雜度也為O(log2N)
2、實現(C++)
#define MAX 100
//構造斐波那契數列
void fibonacci(int *F)
{
F[0] = 0;
F[1] = 1;
for(int i = 2; i < MAX; i++)
{
F[i] = F[i-1] + F[i-2];
}
}
//斐波那契查詢
int fibonacciSearch(int *arr, int value)
{
int len = sizeof(arr)/sizeof(arr[0]);
int low = 0;
int high = len - 1;//構造一個斐波那契數列
int F[MAX];
fibonacci(F);
int k = 0;
while(len > F[k] - 1);//計算len在斐波那契數列中的位置
k++;
int *temp;//將陣列arr擴充套件到F[k]-1長度
temp = new int [F[k] -1];
memcpy(temp, arr, len*sizeof(int));
for(int i = len; i < F[k]-1; i++)
temp[i] = arr[len-1];
while(low < high)
{
int mid = low + F[k-1] -1;
if(value < temp[mid])
{
high = mid - 1;
k -= 1;
}
else if(value > temp[mid])
{
low = mid + 1;
k -= 2;
}
else
{
if(mid < len)
return mid;
else
return len-1;
}
}
delete[] temp;
return -1;
}