1. 程式人生 > >順序查詢,折半查詢,插值查詢

順序查詢,折半查詢,插值查詢

1.順序查詢

從陣列起始掃描到陣列結尾,判斷該索引陣列是否和關鍵字相等,成功返回1

程式碼如下:

//順序查詢
int seqSearch(int *array, int low, int high, int key)
{
    for (int i = low; i < high; i++)
    {
        if (array[i] == key)
            return i;
    }
    return -1;
}

2.折半查詢

適用於有序陣列

不停地拋棄掉一半的結點,例子如下

我們要查詢key=4的結點,獲取中間值mid,mid=(low+high)/2,所以mid=(1+7)/2=4,發現4小於10,則可以鎖定key的位置在mid的左側,此時使mid減一

mid=(1+3)/2=2,我們發現4依然小於8,則鎖定key的區域在mid左邊,mid再減一

此時low=high=1,所以mid=1,以mid為索引的陣列正好等於4,找到key,返回成功

程式碼如下:

//折半查詢(只適用於已經排序好的)
int binarySearch(int *array, int low, int high, int key)
{
    while (low <= high)
    {
        //從中間劃分
        //mid如果不是整數,則直接向下取整,不會影響查詢結果
        int mid = (low + high) / 2
; //正好是中間這個數 if (key == array[mid]) return mid; //數比中間的數大,則在後半部分再切一刀縮小範圍 else if (key > array[mid]) low = mid + 1; //數比中間的數小,則在前半部分再切一刀縮小範圍 else high = mid - 1; } return -1; }

 

3.插值查詢

適用於有序陣列

優化中點mid的選擇,邏輯和折半查詢一致,以更科學的mid點劃分左右區域

//插值查詢(只適用於已經排序好的)
//和折半查詢邏輯一致,修改了mid值
int interpolationSearch(int *array, int low, int high, int key)
{
    while (low <= high)
    {
        //優化中間值
        int mid = low+(key-array[low])/(array[high]-array[low])*(high - low-1);
        //正好是中間這個數
        if (key == array[mid])
            return mid;
        //數比中間的數大,則在下半部分再切一刀縮小範圍
        else if (key > array[mid])
            low = mid + 1;
        //數比中間的數小,則在上半部分再切一刀縮小範圍
        else
            high = mid - 1;
    }
    return -1;
}

4.程式碼彙總+測試

#include<stdlib.h>
#include<iostream>
using namespace std;

int seqSearch(int *array, int low, int high, int key);
int binarySearch(int *array, int low, int high, int key);
int interpolationSearch(int *array, int low, int high, int key);

int main(void)
{
    int * array = new int[100];
    int low = 1;
    int high = 7;
    array[1] = 4;
    array[2] = 8;
    array[3] = 9;
    array[4] = 10;
    array[5] = 11;
    array[6] = 13;
    array[7] = 19;
    int seqResult = seqSearch(array,low,high,4);
    cout << "順序查詢結果是:" << seqResult << endl;
    int binaryResult = binarySearch(array, low, high,8);
    cout << "折半查詢結果是:" << binaryResult << endl;
    int interpolationResult = interpolationSearch(array, low, high, 13);
    cout << "插值查詢結果是:" << interpolationResult << endl;

    delete array;
    system("pause");
    return 0;
}

//順序查詢
int seqSearch(int *array, int low, int high, int key)
{
    for (int i = low; i < high; i++)
    {
        if (array[i] == key)
            return i;
    }
    return -1;
}

//折半查詢(只適用於已經排序好的)
int binarySearch(int *array, int low, int high, int key)
{
    //0 3 5 6 9 11 13 15
    while (low <= high)
    {
        //從中間劃分
        //mid如果不是整數,則直接向下取整,不會影響查詢結果
        int mid = (low + high) / 2;
        //正好是中間這個數
        if (key == array[mid])
            return mid;
        //數比中間的數大,則在後半部分再切一刀縮小範圍
        else if (key > array[mid])
            low = mid + 1;
        //數比中間的數小,則在前半部分再切一刀縮小範圍
        else
            high = mid - 1;
    }
    return -1;
}

//插值查詢(只適用於已經排序好的)
//和折半查詢邏輯一致,修改了mid值
int interpolationSearch(int *array, int low, int high, int key)
{
    //0 3 5 6 9 11 13 15
    while (low <= high)
    {
        //優化中間值
        int mid = low+(key-array[low])/(array[high]-array[low])*(high - low-1);
        //正好是中間這個數
        if (key == array[mid])
            return mid;
        //數比中間的數大,則在下半部分再切一刀縮小範圍
        else if (key > array[mid])
            low = mid + 1;
        //數比中間的數小,則在上半部分再切一刀縮小範圍
        else
            high = mid - 1;
    }
    return -1;
}