数据结构08:查找

1. 查找概论

查找表(Search Table)是由同一类型的数据元素(或记录)构成的集合。
关键字(Key)是数据元素中某个数据项的值。
若此关键字可以唯一地标识一个记录,则称此关键字为主关键字(Primary Key)
对于那些可以识别多个数据元素(或记录)的关键字,我们称为次关键字(Secondary Key)
查找(Searching)就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)。
静态查找表(Static Search Table):只作查找操作的查找表。
动态查找表(Dynamic Search Table):在查找的过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素。

1.1 顺序表查找

顺序查找(Sequential Search)又叫线性查找,是最基本的查找技术,它的查找过程是:从表中第一个(或最后一个)记录开始,逐个进行记录的关键字和给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录;如果直到最后一个(或第一个)记录,其关键字和给定值比较都不等时,则表中没有所查的记录,查找不成功。

1.1.1 顺序表查找算法

/* 顺序查找,a为数组,n为要查找的数组个数,key为要查找的关键字 */
int Sequential_Search(int *a, int n, int key) {
    int i;
    for(i = 1; i <= n; i++) {
        if(a[i] == key)
            return i;
    }
    return 0;
}

1.1.2 顺序表查找优化

/* 有哨兵顺序查找 */
int Sequential_Search2(int *a, int n, int key) {
    int i;
    a[0] = key;
    while(a[i] != key) {
        i--;
    }
    return i;
}

2. 有序表查找

2.1 折半查找

折半查找(Binary Search)技术,又称为二分查找。它的前提是线性表中的记录必须是关键码有序(通常从小到大有序),线性表必须采用顺序存储。折半查找的基本思想是:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功,或所有查找区域无记录,查找失败为止。

/* 折半查找 */
int Binary_Search(int *a, int n, int key) {
    intlow, heigh, mid;
    low = 1;
    high = n;
    while(low < high) {
        mid = (low + high) / 2;
        if(key < a[mid])
            high = mid - 1;
        else if(key > a[mid])
            low = mid + 1;
        else
            return mid;
    }
    return 0;
}

2.2 插值查找

mid = low + (high - low) * (key - a[low]) / (a[hight] - a[low]); /* 插值 */

插值查找(Interpolation Search)是根据要查找的关键字key与查找表中最大最小记录的关机子比较后的查找方法,其核心就在于插值的计算公式key - a[low] / a[hight] - a[low]。

2.3 斐波那契查找

/* 斐波那契查找 */
int Fibonacci_Search(int *a, int n, in key) {
    int low, high, mid, i, k;
    low = 1; /* 定义最低下标为记录首位 */
    high = n; /* 定义最高下标为记录末位 */
    k = 0;
    while(n > F[k] - 1) /* 计算n位于斐波那契竖列的位置 */
        k++;
    for(i = n; i <= F[k] - 1; i++) /* 将不满的数值补全 */
        a[i] = a[n];
    while(low <= high) {
        mid = low + F[k - 1] - 1; /* 计算当前分隔的下标 */
        if(key < a[mid]) { /* 若查找记录小于当前分隔记录 */
            high = mid - 1; /* 最高下标调整到分隔下标mid-1处 */
            k = k - 1; /* 斐波那契竖列小标减一位 */
        } else if(key > a[mid]) { /* 若查找记录大于当前分隔记录 */
            low = mid + 1; /* 最低下标调整到分隔下标mid+1处 */
            k = k - 2; /* 斐波那契竖列下标减两位 */
        } else {
            if(mid <= n)
                return mid; /* 若相等则说明mid即为查找到的位置 */
            else
                return

你可能感兴趣的:(数据结构,数据结构,查找)