一些靜態查找算法

查找表(Search table)是由同一類型的數據元素(或記錄)構成的集合。關鍵字(key)是數據元素中某個數據項的值,又稱爲鍵值,用它可以表示一個數據元素,也可以標識一個記錄的數據項(字段),稱之爲關鍵碼。若此關鍵字可以唯一地標識一個記錄,則稱此關鍵字爲主關鍵字(primary key)。而對於那些可以識別多個數據元素(或記錄)的關鍵字,稱爲次關鍵字(Secondary Key),次關鍵字也可以理解爲不以唯一標識一個數據元素(或記錄)的關鍵字,它對應的數據項就是次關鍵碼。

查找(Searching)就是根據給定的某個值,在查找表中確定一個其關鍵字等於給定值的數據元素(或記錄)。

查找表按照操作方式來分有兩大種:靜態查找表和動態查找表。

靜態查找表(Static Search Table) :只作查找操作的查找表,主要操作爲:

(1)查詢某個“特定的”數據元素是否在查找表中。

(2)檢索某個“特定的”數據元素和各種屬性。

動態查找表(Dynamic Search Table):在查找過程中同時插入查找表中不存在的數據元素,或者從查找表中刪除已經存在的某個數據元素。

(1)查找時插入數據元素。

(2)查找時刪除數據元素。


本文先來說說靜態查找表。

一、順序表查找

順序查找(Sequential Search)又叫線性查找,是最基本的查找技術,它的查找過程是:從表中的一個(或最後一個)記錄開始,逐個進行記錄的關鍵字和給定值比較,若某個記錄的關鍵字和給定值相等,則查找成功,找到所查的記錄;如果直到最後一個(或第一個)記錄,其關鍵字和給定值都比較不相等時,則表中沒有所查的記錄,查找不成功。

二、有序表查找

1、折半查找

折半查找(Binary Search)技術,又稱爲二分查找。它的前提是線性表中的記錄必須是關鍵碼有序(通常從小到大有序),線性表必須採用順序存儲。折半查找的基本思想是:在有序表中,取中間記錄作爲比較對象,若給定值與中間記錄的關鍵字相等,則查找成功;若給定值小於中間記錄的關鍵字,則在中間記錄的左半區繼續查找;若給定值大於中間記錄的關鍵字,則在中間記錄的右半區繼續查找。不斷重複上述過程,直到查找成功,或所有查找區域無記錄,查找失敗爲止。

2、插值查找

插值查找(Interpolation Search)是根據要查找的關鍵字key與查找表中最大最小記錄的關鍵字比較後的查找方法,其核心就在於插值的計算公式 (key-a[low])/(a[high]-a[low]) 。

3、斐波那契查找

斐波那契查找(Fibonacci Search)算法的核心在於

1)當key = a[mid] 時,查找就成功;

2)當key < a[mid] 時,新範圍是第low 個到第mid - 1個,此時範圍個數爲F[k-1]-1個。

3)當key > a[mid] 時,新範圍是第m+1 個到第high個,此時範圍個數爲F[k-2]-1個。

如圖8-4-13所示。


示例代碼如下:(改編自《大話數據結構》)

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
 
#include<iostream>
using namespace std;

#define INFINITLY 65535
#define MAXSIZE 100

int F[100]; /* 斐波那契數列 */

/* 無哨兵順序查找,arr爲數組,n爲要查找的數組個數,key爲要查找的關鍵字 */
/* 返回元素的位置pos (下標+1)*/
int Sequential_Search(int *arr, int n, int key)
{
    for (int i = 0; i < n; i++)
        if (arr[i] == key)
            return i + 1;
    return INFINITLY; //返回無窮說明失敗
}

/* 有哨兵順序查找 */
/* 返回元素的位置pos (下標+1)*/
int Sequential_Search2(int *arr, int n, int key)
{
    arr[n] = key;
    int i = 0;
    while (arr[i] != key)
        i++;
    return i + 1//返回n+1 則說明失敗
}
/* 折半查找 */
/* 返回元素的下標 */
int Binary_Search(int *arr, int n, int key)
{
    int low = 0;/* 定義最低下標爲記錄首位 */
    int high = n - 1;/* 定義最高下標爲記錄末位 */
    int mid;
    while (low <= high)
    {
        mid = (low + high ) / 2;/* 折半 */
        if (key < arr[mid])/* 若查找值比中值小 */
            high = mid - 1;/* 最高下標調整到中位下標小一位 */
        else if (key > arr[mid])/* 若查找值比中值大 */
            low = mid + 1;/* 最低下標調整到中位下標大一位 */
        else
            return mid;/* 若相等則說明mid即爲查找到的位置 */
    }
    return INFINITLY;
}
/* 插值查找 */
int Interpolation_Search(int *arr, int n, int key)
{
    int low = 0;
    int high = n - 1;
    int mid;
    while (low < high)
    {
        /* 插值公式 */
        mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]);
        if (key < arr[mid])
            high = mid - 1;
        else if (key > arr[mid])
            low = mid + 1;
        else
            return mid;
    }
    return INFINITLY;
}

/* 斐波那契查找 */
int Fibonacci_Search(int *arr, int n, int key)
{
    int low = 0;/* 定義最低下標爲記錄首位 */
    int high = n - 1;/* 定義最高下標爲記錄末位 */
    int i, k = 0;
    int mid;

    while (n > F[k] - 1)
        k++;
    for (i = n - 1; i < F[k] - 1; i++)
        arr[i] = arr[n - 1];

    while (low <= high)
    {
        mid = low + F[k - 1] - 1;
        if (key < arr[mid])
        {
            high = mid - 1;
            k = k - 1;
        }
        else if (key > arr[mid])
        {
            low = mid + 1;
            k = k - 2;
        }
        else
        {
            if (mid <= n - 1)
                return mid;
            else
                return INFINITLY;
        }
    }

    return INFINITLY;
}

int main(void)
{
    int arr[MAXSIZE] = {1162435475962738899};
    int result = Sequential_Search(arr, 1024);
    if (result != INFINITLY)
        cout << "24 's pos : " << result << endl;

    result = Sequential_Search2(arr, 1059);
    if (result != sizeof(arr) / sizeof(arr[0]))
        cout << "59 's pos : " << result << endl;

    result = Binary_Search(arr, 1073);
    if (result != INFINITLY)
        cout << "73 's pos : " << result + 1 << endl;

    result = Interpolation_Search(arr, 1016);
    if (result != INFINITLY)
        cout << "16 's pos : " << result + 1 << endl;

    F[0] = 0;
    F[1] = 1;
    for(int i = 2; i < 100; i++)
    {
        F[i] = F[i - 1] + F[i - 2];
    }

    result = Fibonacci_Search(arr, 1088);
    if (result != INFINITLY)
        cout << "88 's pos : " << result + 1 << endl;

    return 0;
}


轉自某大神:http://blog.csdn.net/jnu_simba/article/details/8881708
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章