演算法:靜態尋找表(Static Search Table)(順序尋找、二分尋找、插值尋找、費伯納西尋找)

來源:互聯網
上載者:User

尋找表(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] = {1, 16, 24, 35, 47, 59, 62, 73, 88, 99};
    int result = Sequential_Search(arr, 10, 24);
    if (result != INFINITLY)
        cout << "24 's pos : " << result << endl;

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

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

    result = Interpolation_Search(arr, 10, 16);
    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, 10, 88);
    if (result != INFINITLY)
        cout << "88 's pos : " << result + 1 << endl;

    return 0;
}

輸出為:




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.