zoukankan      html  css  js  c++  java
  • 有序表查找

    1 概念
      查找表(Search Table)是由同一类型的数据元素(或记录)构成的集合。
      查找就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)。
      查找表按照操作方式可以分为两大种:静态查找表和动态查找表。
      (1)静态查找表:只做查找操作的查找表。
      (2)动态查找表:在查找的过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素。

    2 有序表查找

    (1)折半查找(二分查找)
      折半查找的前提是线性表中的记录必须是关键码有序(通常从小到大排序),线性表必须采用顺序存储。

    //折半查找
    int Binary_Search(int *a, int n, int key) {
        int low, high, 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) 插值查找
        折半查找的mid = (low + high)/2 = low + (high - low) * (1/2),也就是mid等于最低下标low加上最高下标high与最低下标low的差的一半。算法科学家将(1/2)改进为(key - a[low])/ (a[high] - a[low]).
        对于表长较大,而关键字分布比较均匀的查找表来说,插值查找的性能比折半查找的性能要高很多。反之,若查找表中的数据{1,2,3,200,300, ..., 8000,9000}分布极度不均匀,则
    插值查找未必是很好的选择。

    (3) 斐波那契查找

    //斐波那契查找
    int Fibonacci_Search(int *a, int n, int 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;                        //斐波那契数列下标减1
            } else if (key > a[mid]) {
                low = mid + 1;                    //最低下标调整到分割下标mid+1处
                k = k - 2;                        //斐波那契数列下标减2
            } else {
                if (mid <= n) {
                    return mid;                    //若相等则说明mid即为查找到的位置
                } else {
                    return n;                    //若mid > n, 说明是补全数值,返回n
                }
            }
        }
        return 0;
    }

    3 三种查找方法比较
        折半查找是进行加法和除法运算 mid = low + (high - low)/2, 插值查找是进行复杂的四则运算 mid = low + (high - low) * (key - a[low])/(a[high] - a[low]), 而斐波那契查找只是最简单的加减法运算 mid = low + F[k - 1] - 1, 在海量数据的查找过程中,这种细微的差别可能会影响最终的查找效率。
        三种查找的本质区别是分隔点的选择不同,各有优劣,实际开发中可根据数据的特点综合考虑后再做决定。

  • 相关阅读:
    android中listview分页加载数据
    android listview的HeadView左右切换图片(仿新浪,网易,百度等切换图片)
    Opencv cvCircle函数
    我是怎样成长为系统架构师的
    C++游戏编程(一开篇)
    cidaemon.exe进程cpu占用率高及关闭cidaemon.exe进程方法
    curl命令具体解释
    HDU 4334 Trouble
    美国地名大全(美国城市名称英文、中文)
    几种常见模式识别算法整理和总结
  • 原文地址:https://www.cnblogs.com/muzijie/p/5715991.html
Copyright © 2011-2022 走看看