查找算法-4种常用的查找算法

2021/9/13 14:05:18

本文主要是介绍查找算法-4种常用的查找算法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

  • 一、排序算法是什么?
    • 1.算法解读
    • 2.查找算法简介
  • 二、查找算法介绍及实现
    • 1.顺序查找
      • 算法描述
      • 代码实现:
    • 2.二分查找/折半查找
      • 算法描述
      • 代码实现:
    • 3.插值查找
      • 算法描述
      • 代码实现:
    • 4.斐波那契查找
      • 算法描述
      • 代码实现:


一、排序算法是什么?

1.算法解读

这里引入百度百科的解释:

  • 谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
  • 排序算法,就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面。一个优秀的算法可以节省大量的资源。
  • 在各个领域中考虑到数据的各种限制和规范,要得到一个符合实际的优秀算法,得经过大量的推理和分析。

2.查找算法简介

  • 查找是在大量的信息中寻找一个特定的信息元素,在计算机应用中,查找是常用的基本运算
  • 比较常见的有顺序查找(线性查找)
  • 二分查找/折半查找
  • 插入查找
  • 斐波那契(黄金比例)查找

二、查找算法介绍及实现

1.顺序查找

算法描述

  • 对数据进行逐一对比
  • 检索到指定数据,则停止检索,返回其下标

代码实现:

package com.lingo.search;

/**
 * 线性查找/顺序查找  最基本最基础的循环查找  也是效率最低的查找方式
 */
public class SequentialSearch {

    public static void main(String[] args) {
        int[] arr = {1, 5, 8, 66, 55, 1, 2, 33, 555, 156, 498, 512, 223, 156};
        int result = sequentialSearch(arr, 555);
        System.out.println(result);
    }

    public static int sequentialSearch(int[] arr, int value) {
        for (int i = 0; i < arr.length; i++) {
            if (value == arr[i]) {
                return i;
            }
        }
        return -1;
    }

}

输出结果:

8


2.二分查找/折半查找

算法描述

  • 进行二分查找或折半查找的前提是当前数组一定是有序的
  • 取出数组的中间值:mid = left + (right - left)/2
  • 这里为什么不直接用left+right呢?(可能会存在数据大小越界问题)
  • 若待查找数据小于中间值 则向左递归查询
  • 若待查找数据大于中间值 则向右递归查询
  • 最终返回待查找数据的下标,若无数据则返回-1

代码实现:

package com.lingo.search;

public class BinarySearchT {

    private static int search(int[] arr, int left, int right, int value) {

        //递归中止条件
        if (left > right) {
            return -1;
        }

        int mid = left + (right - left) / 2;
        if (value < arr[mid]) {
            return search(arr, left, mid, value);
        } else if (value > arr[mid]) {
            return search(arr, mid + 1, right, value);
        } else {
            return mid;
        }

    }

    public static int search(int[] arr, int value) {
        return search(arr, 0, arr.length - 1, value);
    }

    public static void main(String[] args) {
        int[] arr = {1, 5, 8, 15, 55, 212, 333, 411, 555};
        int result = search(arr, 333);
        System.out.println(result);
    }

}

输出结果:

6


3.插值查找

算法描述

  • 插值查找相当于是二分查找的一个plus版本
  • 插值查找的mid是一个自适应的mid
  • mid = low + (high - low)*(value-arr[low])/(arr[high] - arr[low])
  • 其他算法流程同二分查找

代码实现:

package com.lingo.search;

public class InsertionSearchT {

    private static int search(int[] arr, int left, int right, int value) {

        //递归中止条件
        if (left > right) {
            return -1;
        }
        //这里如果不加判断会导致空指针异常
        if (value > arr[arr.length - 1] || value < arr[0]) {
            return -1;
        }
        int mid = left + (right - left) * (value - arr[left]) / (arr[right] - arr[left]);
        if (value < arr[mid]) {
            return search(arr, left, mid, value);
        } else if (value > arr[mid]) {
            return search(arr, mid + 1, right, value);
        } else {
            return mid;
        }

    }

    public static int search(int[] arr, int value) {
        return search(arr, 0, arr.length - 1, value);
    }

    public static void main(String[] args) {
        int[] arr = {1, 5, 8, 15, 55, 212, 333, 411, 555};
        int result = search(arr, 212);
        System.out.println(result);
    }

}


输出结果:

5


4.斐波那契查找

算法描述

  • 黄金比例
  • 斐波那契数列{1,1,2,3,5,8,13,21,34,55,…}
  • 斐波那契数列的特点是从第三位开始 数值等于 前两位数值的加和
  • 正是采用这种思想将待排序数组的数量对应于大于或等于该数组数量且最接近的数值,然后copyOf到新数组
  • 将新数组中大于原数组长度的数值更新为原数组的最大值
  • mid = low + F[k-1] - 1
  • 因为F[k]为数组长度 F[k-1]为左侧元素数组 F[k-2]为右侧元素数组
  • 这里的-1 是因为数组的下标从0开始
  • 这里采用了迭代的查找

代码实现:

package com.lingo.search;

import java.util.Arrays;

public class FibonaciiSearchT {

    private static int maxSize = 20;

    public static int search(int[] arr, int value) {
        if (arr[0] > value || arr[arr.length - 1] < value) {
            return -1;
        }
        int[] f = getFibonaciiArr();
        int low = 0;
        int k = 0;//斐波那契数列下标
        int high = arr.length - 1;
        while (high > f[k]) {
            k++;
        }
        int[] copyArr = Arrays.copyOf(arr, f[k]);
        for (int i = high + 1; i < copyArr.length; i++) {
            copyArr[i] = arr[high];
        }
        while (low <= high) {
            int mid = low + f[k - 1] - 1;//下标0开始
            if (value > copyArr[mid]) {
                //f[k] = f[k-1]+f[k-2]
                low = mid + 1;
                k -= 2;
            } else if (value < copyArr[mid]) {
                high = mid - 1;
                k -= 1;
            } else {
                if (mid <= high) {
                    return mid;
                } else {
                    return high;
                }
            }
        }
        return -1;
    }

    private static int[] getFibonaciiArr() {
        int[] f = new int[maxSize];
        f[0] = 1;
        f[1] = 1;
        for (int i = 2; i < maxSize - 1; i++) {
            f[i] = f[i - 1] + f[i - 2];
        }
        return f;
    }

    public static void main(String[] args) {
        int[] arr = {1, 5, 8, 15, 55, 212, 333, 411, 555};
        int result = search(arr, 212);
        System.out.println(result);
    }

}

输出结果:

5



这篇关于查找算法-4种常用的查找算法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程