zoukankan      html  css  js  c++  java
  • 查找算法

    一、线性查找

      源码:线性查找

    1,思路

      线性查找又称顺序查找,是一种最简单的查找方法,它的基本思想是从第一个记录开始,逐个比较记录的关键字,直到和给定的K值相等,则查找成功;若比较结果与文件中n个记录的关键字都不等,则查找失败。

    2,特点

    • 按顺序查找,数组(集合)可以无序  
    • 时间复杂度:O(N)

    3,代码实现

    /**
     * 线性查找找到一个满足条件的值就返回
     */
    public static int seqSearch(int[] arr, int value) {
        // 线性查找是逐一比对,发现有相同值,就返回下标
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == value) {
                return i;
            }
        }
        return -1;
    }
    View Code

    二、二分查找(折半)

      源码:二分查找

    1,思路

    1)定义两个辅助指针:left、right ,待查找的元素在 arr[left]~arr[right] 之间
    2)eft 初始值为 0 ,right 初始值为 arr.length - 1
    3)将数组分成两半:int mid = (left + right) / 2; ,取数组中间值与目标值 findVal 比较
        如果 mid > val,说明待查找的值在数组左半部分,令right = mid-1 递归查
        如果 mid < val ,说明待查找的值在数组右半部分,令left = mid+1递归查
        如果 mid == val,查找到目标值,返回mid即可
    4)未找到目标值:left > right ,直接返回-1

    2,特点

    • 数组(集合)必须有序
    • 时间复杂度:O(log2N)

    3,代码实现

    /**
     * 二分查找算法
     */
    public static int binarySearch(int[] arr, int left, int right, int val) {
        if (left > right) {
            return -1;
        }
        int mid = (left + right) / 2;
        if (val > arr[mid]) {
            return binarySearch(arr, mid + 1, right, val);
        } else if (val < arr[mid]) {
            return binarySearch(arr, left, mid - 1, val);
        } else {
            return mid;
        }
    }
    View Code

    三、插值查找

      源码:插值查找

    1,介绍

    • 插值查找算法类似于二分查找, 不同的是插值查找每次从自适应 mid 处开始查找。
    • 求mid的公式为:int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low])

      

    2,思路

    基本与二分查找相同,不同之处为:
    1,求mid的公式不同:int mid = left + (right – left) * (findVal – arr[left]) / (arr[right] – arr[left])
    2,判断未找到目标:left>right || val< arr[left] || val> arr[right]

    3,特点

    • 数组(集合)必须有序
    • 对于数据量较大,关键字分布比较均匀(最好是线性分布)的查找表来说,采用插值查找,速度较快
    • 时间复杂度:O(log2(log2N))

    4,代码实现

    public static int insertValSearch(int[] arr,int left , int right,int val) {
        System.out.println("插值查找~~");
        if (left > right || arr[left] > val || arr[right] < val) {
            return -1;
        }
        int mid = left + (right - left) * (val - arr[left]) / (arr[right] - arr[left]);
        if (val > arr[mid]) {
            return insertValSearch(arr, mid + 1, right, val);
        } else if (val < arr[mid]) {
            return insertValSearch(arr, left, mid - 1, val);
        }else {
            return mid;
        }
    }
    View Code

    四、斐波拉契查找算法

      源码:斐波拉契查找算法

    1,思路 

     参考:斐波拉契查找简介

    2,特点

    • 如果要查找的记录在右分区,则左分区的数据都不用再判断了,不断反复进行下去,对处于当中的大部分数据,其工作效率要高一些。所以,尽管斐波那契查找时间复杂度也为O(logn),但就平均性能来说,斐波那契查找要优于折半查找。可惜如果是最坏的情况,比如这里的key=1,那么始终都处于左分区在查找,则查找效率要低于折半查找。左分区要比右分区大嘛。
    • 时间复杂度:O(log2N)

    3,代码

    /**
     * 查找
     */
    public static int fibonacciSearch(int[] arr, int val) {
        int left = 0;
        int right = arr.length - 1;
        int[] f = fib();
        int k = 0;
        while (right > f[k] - 1) {
            k++;
        }
        //拷贝临时数组  比原始数组长的部分会直接用0补齐
        int[] temp = Arrays.copyOf(arr, f[k]);
        //将长于arr部分用高位值补齐
        for (int i = right + 1; i < temp.length; i++) {
            temp[i] = arr[right];
        }
        int mid = 0;
        while (left <= right) {
            mid = left + f[k - 1] - 1;
            if (val < temp[mid]) {
                //向左找
                right = mid - 1;
                k--;
            } else if (val > temp[mid]) {
                //向右找
                left = mid + 1;
                k -= 2;
            } else {
                if (mid < right) {
                    return mid;
                } else {
                    //如果查到的是扩容之后的数值,就直接返right
                    return right;
                }
            }
    
        }
        return -1;
    }
    View Code
  • 相关阅读:
    制作一个Frame用于保存文件和打开文件
    制作一个Frame界面显示盘符的东西
    制作一个图形化界面(演示键盘和鼠标的监听)
    编码解码练习---截取字节
    编码解码问题
    一些在内存里面操作的流
    类型流DataInputstream 和DataOutputStream的用法
    管道流 PipedInputStream和PipedOutputStream 用法
    RandomAccessFile的用法
    面向对象的更多说明
  • 原文地址:https://www.cnblogs.com/bbgs-xc/p/14111312.html
Copyright © 2011-2022 走看看