数据结构--有序表查找

对于已经排好序的表,有

1、折半查找

在有序表中,取中间的记录进行比较,如果相同,匹配成功。如果比中间值小,就在中间记录的左半区进行查找,如果大,就在右半区。

public static int binarySearch(int key){
    int height = src.length-1;
    int low = 0;
    int mid = 0;

    while(low <= height) {
        mid = (height+low)/2;//对下标取半

        if(key < src[mid]) //如果比中间值小,改变height的值
            height = mid-1;
        else  if(key > src[mid])//如果比中间值大,改变low的值
            low = mid+1;
        else
            return mid;
    }

    return -1;
}

2、插值查找

插值查找是对折半查找的改进。
折半时 mid = (low+height)2 = low2 + height2 = low- low2 + height2 = low+ 12 (height-low)
折半查找是按1/2进行查找,如果有10000个有序数组找一个很小的数5,就有了优化的空间。
将查mid的公式替换为mid=low+ keya[low]a[height]a[low] (height-low) 即按比例获取要比较的中间值

3、斐波那契查找

斐波那契相邻的数接近黄金分割,与折半类似,只是切割的范围为黄金分割点。平均效率高于折半,最坏的效率比折半差

public static void main(String[] args) {
     int[] src = { 1, 5, 15, 22, 25, 31, 39, 42, 47, 49, 59, 68, 88 };

     System.out.println("==>" + FBSearch(src, 88));
 }

 public static int FBSearch(int array[], int key){
     int mid,k=0;
     int fibon[] = getFibon(20);//构建斐波那契数组

     while(array.length > fibon[k]-1)   //查找比数组长度大的斐波那契数
         ++k;

     int tmp[] = Arrays.copyOf(array, fibon[k]-1);//将原数组长度扩展为斐波那契数的长度
     for (int i = array.length; i < tmp.length; i++)  //将扩展的部分填充为原数组最后一个数据
         tmp[i] = array[array.length-1];

     int low = 0;
     int high = fibon[k]-1;
     while(low <= high) {
         mid = low + fibon[k-1]-1;

         if(key < tmp[mid]) {
             high = mid-1;
             k -= 1;
         } else if (key > tmp[mid]) {
             // 查找后半部分,高位指针移动
             low = mid+1;
             // (全部元素) = (前半部分)+(后半部分)
             // f[k] = f[k-1] + f[k-2]
             // 因为后半部分有f[k-2]个元素,所以 k = k-2
             k -= 2;
         } else {
             return mid<=array.length?mid:array.length;//如果mid大于原数组长度,则表示是原数组的最后一个
         }
     }

     return -1;
 }

 //获取斐波那契数组
 public static int[] getFibon(int len){
     int fibon[] = new int[len];
     fibon[0] = fibon[1] = 1;

     for (int i = 2; i < len; i++) {
         fibon[i] = fibon[i-1] + fibon[i-2];
     }

     return fibon;
 }

参考:大话数据结构

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值