有序表查找算法(折半,插值,斐波那契)

今天总结了有序表查找常用的三种算法与大家分享。

1.折半查找
折半查找又称二分查找,它的基本思想是:在有序表中,取中间记录作为比较对象,若相等则查找成功;若给定值小于中间记录的关键字,则在中间记录左半区继续查找,若给定值大于中间值,则在又半区寻找,不断重复以上过程。

算法代码(java版)

int binarySearch(int[] a,int key){
        int low,high,mid;
        low = 0;
        high = a.length-1;
        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 -1;
}

时间复杂度为O(logn) ,显然好于顺序查找的时间复杂度O(n)。

2.插值查找

折半查找在某些情况下也明显不足,在大小分布均匀的数组中查找,折半查找可能就会浪费很多时间。
折半查找中 mid=(low+high)/2 = low+(high-low)/2;
算法科学家们将此等式加以改进于是 将1/2替换成(key-a[low])/(a[high]-a[low]),于是就有了mid = low+(high-low)*(key-a[low])/(a[high]-a[low]);

算法代码(java版)

public int insertSearch(int[] a,int key){
        int low,high,mid;
        low = 0;
        high = a.length-1;
        while(low<=high){
            mid = low+(high-low)*(key-a[low])/(a[high]-a[low]);
            if(key<a[mid])
                high = mid-1;
            else if(key>a[mid])
                low = mid+1;
            else
                return mid;
        }
        return -1;
}

插值查找的时间复杂度也是O(logn),但是对于关键字分布均匀的查找表来说,平均性能比折半查找好得多。

3.斐波那契查找

利用黄金分割进行查找
其核心思想是当 key=a[mid]时查找成功,当key<a[mid]时,新的范围是第low个到地mid-1个,此时范围个数为F[k-1]-1个,当key>a[mid]时,新的范围是第low个到地mid+1个,此时范围个数为F[k-2]-1个。

算法实例(java版)

public int FibonacciSearch(int[] a,int key){
        int low,high,mid,k=0;
        low=0;
        high=a.length;
        while(a.length>fibonacci(k)-1)
            k++;
        for(int i=a.length;i<fibonacci(k)-1;i++)
            a[i] = a[a.length-1];
        while(low<=high){
            mid = low+fibonacci(k-1)-1;
            if(key<a[mid]){
                high = mid-1;
                k=k-1;
            }
            else if(key>a[mid]){
                low=mid+1;
                k=k-2;
            }
            else{
                if(mid<=a.length)
                    return mid;
                else
                    return a.length;
            }
        }
        return -1;
    }

    public int fibonacci(int n){
        return n>2?fibonacci(n-1)+fibonacci(n-2):1;
    }

斐波那契查找的时间复杂度也是O(logn),但就平均性能来说,优于折半查找。果是最坏的情况,比如这里key=1,那么始终都处于左侧在查找,则查找效率低于折半查找。

时间: 2024-08-29 14:15:28

有序表查找算法(折半,插值,斐波那契)的相关文章

分治法--二分查找、乘方、斐波那契数

1.二分查找 常见错误: 死循环:循环体外的初始化条件,与循环体内的迭代步骤, 都必须遵守一致的区间规则,也就是说,如果循环体初始化时,是以左闭右开区间为边界的,那么循环体内部的迭代也应该如此.如果两者不一致,会造成程序的错误. 溢出:middle = left + (right - left) / 2 终止条件:一般来说,如果左闭右闭,则left<=right: 如果一开一闭,则left<right: 关键看left能不能等于right,而且要考虑实际情况,有时不能这样简单终结,会出现死循环

算法——动态规划篇——斐波那契数列

斐波那契数列,又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.--在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)在现代物理.准晶体结构.化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1960年代起出版了<斐波纳契数列>季刊,专门刊载这方面的研究成果. 以上内容来自百度百科.. 今天主要是想用动态规划的思想求解斐波那契数列,用来观察动态规划带来的优势,空间换时间,不重复求解

"二分查找(Binary Search)"与"斐波那契查找(Fibonacci Search)"

首先,我们来看一个笔者的拙作,一段二分查找代码 //返回值是key的下标,如果A中不存在key则返回-1 template <class T> int BinSearch(T* A, const T &key, int lo, int hi) {     int mid;     while(lo<hi)     {         mid = lo + (hi-lo)/2;         if(key < A[mid])             hi = mid-1;

算法笔记_001:斐波那契数的多种解法

本篇文章解决的问题来源于算法设计与分析课程的课堂作业,主要是运用多种方法来计算斐波那契数.具体问题及解法如下: 一.问题1: 问题描述:利用迭代算法寻找不超过编程环境能够支持的最大整数的斐波那契数是第几个斐波那契数.(Java: 231-1 for int, 263-1 for long) 解决方案:针对问题1,此处要使用迭代法来解决,具体实现代码如下: //用迭代法寻找编程环境支持的最大整数(int型)的斐波那契数是第几个斐波那契数 public static int max_int_iter

[莫队算法 线段树 斐波那契 暴力] Codeforces 633H Fibonacci-ish II

题目大意:给出一个长度为n的数列a. 对于一个询问lj和rj.将a[lj]到a[rj]从小到大排序后并去重.设得到的新数列为b,长度为k,求F1*b1+F2*b2+F3*b3+...+Fk*bk.当中F为斐波那契数列.F1=F2=1.对每一个询问输出答案模m. 区间查询离线 用莫队算法 开棵权值线段树,然后用斐波那契的性质update F(n+m)=F(n+1)*F(m)+F(n)*F(m-1); #include<cstdio> #include<cstdlib> #includ

ABAP算法题:斐波那契(Fibonacci)数列

斐波那契(Fibonacci)数列是经典的递推关系式定义的数列. 第一项是0,第二项是1,之后的每一项都是前面两项之和. (sap labs面试题,要求用不同的方法在白板上写abap算法...毫无心理准备,第一遍写了一个递归,可能是复杂度不太好,面试官让我再写一个,于是写了如下代码) PARAMETERS: p_number TYPE i OBLIGATORY. DATA : x TYPE i VALUE 0, y TYPE i VALUE 1. " 算法1 CASE p_number. WHE

高级算法——动态规划(斐波那契函数实例)

//使用递归去解决问题虽然简洁, 但效率不高,转为动态规划较好 function recurFib(n) {//斐波那契数列——递归 if (n <= 2) { return 1; } else { return recurFib(n - 1) + recurFib(n - 2); } } function dynFib(n) {//斐波那契数列——动态规划 var val = []; if (n == 1 || n == 2) { return 1; } else { val[1] = 1;

4月5日--关于算法的练习题--斐波那契数--杨辉三角形

/*要求:定义一个函数,接受一个正整数,返回该参数对应的斐波那契数介绍:斐波那契数前2个数都是1 ,从第三个开始都是前2个数之和,如下:1 .1.2.3.5.8.13.21.34--*/ <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script type="text

算法——动态规划篇——斐波那契数

契数列,又称黄金切割数列.指的是这样一个数列:0.1.1.2.3.5.8.13.21.--在数学上.斐波纳契数列以例如以下被以递归的方法定义:F0=0.F1=1,Fn=F(n-1)+F(n-2)(n>=2.n∈N*)在现代物理.准晶体结构.化学等领域,斐波纳契数列都有直接的应用,为此.美国数学会从1960年代起出版了<斐波纳契数列>季刊,专门刊载这方面的研究成果. 以上内容来自百度百科.. 今天主要是想用动态规划的思想求解斐波那契数列.用来观察动态规划带来的优势,空间换时间.不反复求解