5.顺序查找、二分查找、插值查找、斐波那契查找

一、顺序查找

  顺序查找又叫线性查找法,是将数据一项一项地按顺序逐个查找,不管数据顺序如何,都得从头到尾遍历一次(在抽屉中逐层查找东西,也是顺序查找的应用)。

优点:文件在查找前不需要进行任何处理和排序

缺点:查找速度慢,适用于小数据文件的查找

代码实现:

public class Test3 {
    public static void main(String[] args) {
        //线性查找 linearSearch
        /*
        最好情况 查1, 1次就出来
        最坏情况 查3, 9次出来
        当数组长度越大的话,最坏情况就越差
        时间复杂度(最坏情况) O(n)线性阶
         */
        int[] arr ={1,2,4,12,7,6,5,9,3};
        int key=9;//要找的数
        int index=-1;//-1意味着找不到
        for (int i=0;i<arr.length;i++){
            if (arr[i]==key){
                index=i;
                break;
            }
        }
        System.out.println(index);
    }
}

二、二分查找

  二分查找的数据事先已经排好序了,二分查找法是将数据分割成两等份,再比较键值与中间值的大小,如果键值小于中间值,可确定要查找的数据在前半部分,否则在后半部分,直到找到或不确定为止。

举个栗子:

已排序好的数组:2 3 5 8 9 11 12 16 18   键值:11

(1)首先和中值比较,与第五个值9比较,如下图所示:

(2)因为11>9,所以再和后半部分的中间值12比较,如下图所示

(3)因为11<12,所以和前半部分中间值11比较,如下图所示:

(4)因为11=11,查找结束

代码实现:

public class Test3 {
    public static void main(String[] args) {
        //二分查找 binarySearch 前提 数组必须有序
         /*
        最好情况 查46 1次就出来了
        最坏情况 查12/60 O(logn)
        */
        int[] arr1={12,17,21,32,38,41,46,49,50,50,51,59,60};
        int key1=46;
        int index1=-1;
        int min_index=0;
        int max_index=arr1.length-1;
        int mid_index=(min_index+max_index)/2;
        while(arr1[mid_index]!=key1){
            if(key1<arr1[mid_index]){
                max_index=mid_index-1;
            }
            if(arr1[mid_index]<key1){
                min_index=mid_index+1;
            }
            if(min_index>max_index){
                index1=-1;
                break;
            }
            mid_index=(min_index+max_index)/2;
        }
        System.out.println(mid_index);
    }
}

三、插值查找

  插值查找又称插补查找,是二分查找的改进版。它是按照数据位置的分布,利用公式预测数据所在的位置,再以二分法的方式渐渐逼近。使用插值法的前提是假设数据平均的分布在数组中,而每一项数据的差距相当接近或有一定的距离比例。插值法的公式为:

  其中key是要查找的值,data[high]、data[low]是剩余待查找记录中的最大值和最小值,假设数据项数为n,其步骤如下:

  1. 将记录由小到大的顺序设置为1,2,3,....n的编号
  2. 令low=1,high=n
  3. 当low<high时,重复执行4和5
  4. 若key<keymid且high不等于Mid-1,则令high=Mid-1
  5. 若key=keymid表示成功寻找键值的位置
  6. 若key>keymid且high不等于Mid-1,则令low=Mid+1.

注意:一般来说,插值寻找法优于顺序查找法,而如果数据的分布越平均,则查找速度越快,时间复杂度取决于数据分布的情况而定。

四、斐波那契查找

斐波那契查找法与二分法一样都是以分割范围来进行查找,不同的是斐波那契查找法不是对半分割,而是以斐波那契级数的方式来分割。

斐波那契级数:0,1,1,2,3,5,8,13,21,34,55,89....除了第0个和第1个元素外,级数中的每个值都是前两个值得和。

斐波那契查找法是以斐波那契树来寻找数据,如果数据的个数为n,而且n比某一个斐波那契数小,满足该表达式:Fib(k+1)≥n+1.

public static int fibonacciSearch(int[] lookupTable,int[] f,int target){
    int low = 0;
    int high = lookupTable.length - 1;
    int k = 0;// k 是 Fibonacci 分割数组下标
    int middle = 0;
    while (f[k] < high){
        k ++;
    }
    int[] temp = Arrays.copyOf(lookupTable,f[k]);
    while (low <= high){
        middle = low + f[k - 1];
        if (target < lookupTable[middle]){
            high = middle -1;
            k --;
        }else if (target > lookupTable[middle]){
            low = middle + 1;
            k -= 2;
        }else{
            return middle < high ? middle : high;
        }
    }
    return -1;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值