一些静态查找算法

查找表(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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值