美文网首页
静态查找

静态查找

作者: lkmc2 | 来源:发表于2018-08-23 16:29 被阅读8次

静态查找:只对表进行查找操作,不会动态添加元素。

平均时间复杂度
顺序查找:O(n)
二分查找:O(logn)
插值查找:O(logn),表长较大,关键字分布均匀时,平均性能比二分查找好
斐波那契查找:O(logn),平均性能优于二分查找

// 静态查找
#include <stdio.h>

#define MAXSIZE 100 // 数组存储空间初始分配量

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

/**
 * 顺序查找
 * @param a 数组
 * @param n 数组个数
 * @param key 要查找的关键字
 * @return 关键字在数据中的下标(返回0表示未找到该元素)
 */
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;
}

/**
 * 带哨兵的顺序查找
 * @param a 数组
 * @param n 数组个数
 * @param key 要查找的关键字
 * @return 关键字在数据中的下标(返回0表示未找到该元素)
 */
int Sequential_Search_With_Guard(int *a, int n, int key) {
    int i; // 用来遍历元素
    a[0] = key; // 将关键词设置的数组第0个元素(哨兵)

    i = n; // i的初始值设置为数组长度

    while (a[i] != key) { // 该位置的元素不等于关键字
        i--; // 数组下标向前移动
    }
    return i; // 返回关键字的下标
}

/**
 * 二分查找(折半查找)
 * @param a 数组
 * @param n 数组个数
 * @param key 要查找的关键字
 * @return 关键字在数据中的下标(返回0表示未找到该元素)
 */
int Binary_Search(int *a, int n, int key) {
    int low, high, mid; // 当前查找范围最小、最大、中间下标

    low = 1; // 设置查找范围最小下标为数组起点下标(不考虑0下标)
    high = n; // 设置查找范围最大下标为数组终点下标

    while (low <= high) {
        mid = (low + high) / 2; // 求中间下标

        if (key < a[mid]) { // 关键字小于中间位置下标的值
            high = mid - 1; // 最大下标设置为中间下标减1
        } else if (key > a[mid]) { // 关键字大于中间位置下标的值
            low = mid + 1;  // 最小下标设置为中间下标加1
        } else { // 关键字等于中间位置下标的值
            return mid; // 返回该位置下标
        }
    }
    return 0;
}

/**
 * 插值查找(在二分查找基础上将求mid的过程换成插值公式)
 * @param a 数组
 * @param n 数组个数
 * @param key 要查找的关键字
 * @return 关键字在数据中的下标(返回0表示未找到该元素)
 */
int Interpolation_Search(int *a, int n, int key) {
    int low, high, mid; // 当前查找范围最小、最大、中间下标

    low = 1; // 设置查找范围最小下标为数组起点下标(不考虑0下标)
    high = n; // 设置查找范围最大下标为数组终点下标

    while (low <= high) {
        // 插值公式求中间值下标
        mid = low + (high - low) * (key - a[low]) / (a[high] - a[low]); 

        if (key < a[mid]) { // 关键字小于中间位置下标的值
            high = mid - 1; // 最大下标设置为中间下标减1
        } else if (key > a[mid]) { // 关键字大于中间位置下标的值
            low = mid + 1;  // 最小下标设置为中间下标加1
        } else { // 关键字等于中间位置下标的值
            return mid; // 返回该位置下标
        }
    }
    return 0;
}

/**
 * 斐波那契查找(在二分查找基础上将求mid的过程换成利用斐波那契数组求值)
 * @param a 数组
 * @param n 数组个数
 * @param key 要查找的关键字
 * @return 关键字在数据中的下标(返回0表示未找到该元素)
 */
int Fibonacci_Search(int *a, int n, int key) {
    int low, high, mid; // 当前查找范围最小、最大、中间下标
    int i, k = 0; // i用来遍历元素,k用来定位在斐波那契数列的位置

    low = 1; // 设置查找范围最小下标为数组起点下标(不考虑0下标)
    high = n; // 设置查找范围最大下标为数组终点下标

    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; // 最大下标设置为中间下标减1
            k = k - 1;
        } else if (key > a[mid]) { // 关键字大于中间位置下标的值
            low = mid + 1;  // 最小下标设置为中间下标加1
            k = k - 2;
        } else { // 关键字等于中间位置下标的值
            if (mid <= n) {
                return mid;  // 若相等则说明mid为找到的位置
            } else {
                return n; // mid > n说明是补全数字,返回n
            }
        }
    }
    return 0;
}

int main() {
    int i, result;
    int arr[MAXSIZE] = {0, 1, 15, 27, 36, 49, 53, 61, 73, 84, 99};

    result = Sequential_Search(arr, 10, 73); // 顺序查找
    printf("顺序查找的结果为:%d\n", result);

    result = Sequential_Search_With_Guard(arr, 10, 73); // 带哨兵的顺序查找
    printf("带哨兵的顺序查找的结果为:%d\n", result);

    result = Binary_Search(arr, 10, 73); // 二分查找
    printf("二分查找结果为:%d\n", result);

    result = Interpolation_Search(arr, 10, 73); // 插值查找
    printf("插值查找结果为:%d\n", result);

    /********** 初始化斐波那契数组 **********/
    F[0] = 0;
    F[1] = 1;

    for (i = 2; i < MAXSIZE; i++) {
        F[i] = F[i - 1] + F[i - 2];
    }
    /***************************************/

    result = Fibonacci_Search(arr, 10, 73); // 斐波那契查找
    printf("斐波那契查找结果为:%d\n", result);

    return 0;
}
运行结果

相关文章

  • 据结构与算法学习-查找与二叉排序树

    查找表操作方式分为静态查找和动态查找。静态查找表(Static Search Table): 只作查找操作的查找表...

  • PHP查找算法

    静态查找 顺序查找 折半查找 递归折半查找

  • 查找算法总结及其算法实现(Python/Java)

    -----正文开始----- 预备知识 查找算法分类 1)静态查找和动态查找; 注:静态或者动态都是针对查找表而言...

  • 二叉树的基本操作(FID)

    二叉搜索树 首先回顾一下:查找问题: 静态查找与动态查找; 针对动态查找,数据如何组织; 静态查找:要查找的元素是...

  • 二叉搜索树、平衡二叉树

    -二叉搜索树 查找问题:静态查找和动态查找,静态查找可以用二分查找-判定树,那么针对动态查找数据如何组织?(树的动...

  • 静态查找

    静态查找:只对表进行查找操作,不会动态添加元素。 平均时间复杂度顺序查找:O(n)二分查找:O(logn)插值查找...

  • 2018-03-30 算法 :查找简介

    世界上没有最好的算法,只有最合适的算法 查找算法:静态查找,动态查找 静态查找(一般使用线性表)的分类: 顺序查找...

  • 数据结构与算法学习 (16)查找与二叉排序树

    查找:根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)。1)静态查找和动态查找;注:静态...

  • 六、查找

    六、查找 1. 静态查找表 静态查找表在查找过程中不改变表中数据——不插不删,故采用顺序存储结构。它适用于数据不变...

  • 数据结构比较(树)

    查找方法:静态查找:1、顺序查找 : O(N)2、二分查找(Binary Search):O(logN)前提:有序...

网友评论

      本文标题:静态查找

      本文链接:https://www.haomeiwen.com/subject/gvrmiftx.html