1)顺序查找或叫线性查找

就是顺序遍历匹配

2)二分查找

package search;public class BinarySearch {/*** 二分查找数组必须有序*//**** @param arr 数组* @param left  左边索引* @param right 右边索引* @param findVal   要查找的值* @return 找到就返回,找不到返回-1*/public static int binarySearch(int [] arr, int left, int right, int findVal){int mid = (left + right)/2;int midVal = arr[mid];if (left > right){  //说明没有找到return -1;}if (findVal > midVal){ //向右递归return binarySearch(arr,mid + 1,right,findVal);} else if (findVal < midVal ){ // 向左递归return binarySearch(arr, left,mid - 1,findVal);}else { //找到return mid;}}public static void main(String []args){int arr [] = {1,2,3,4,5,6,7,8,9};System.out.println(binarySearch(arr,0,arr.length-1,20));}
}

那么如果有多个相同的数,怎么全部都找出来?

就是在找到值后,先不返回加入到ArrayList,而是向左向右扫描是否有一样的,有就加入到ArrayList。最后再返回ArrayList,没找到返回一个空的ArrayList。

package search;import java.util.ArrayList;public class BinarySearch {public static ArrayList<Integer> arrayList = new ArrayList<>();public static ArrayList<Integer> binarySearch1(int [] arr, int left, int right, int findVal){int mid = (left + right)/2;int midVal = arr[mid];if (left > right){  //没找到返回一个空的集合,根据size就可以判断return new ArrayList<>();}if (findVal > midVal){ //向右递归return binarySearch1(arr,mid + 1,right,findVal);}else if(findVal < midVal){ //向左递归return binarySearch1(arr,left,mid - 1, findVal);}else {/*** 思路分析* 1. 找到mid索引值不直接返回* 2. 向mid索引值的左边扫描,与midVal一样就把下标存到ArrayList* 3. 向mid索引值的右边扫描,与midVal一样就把下标存到ArrayList* 4. 将ArrayList返回*///1.找到mid索引值不直接返回,而是加到ArrayList里arrayList.add(mid);//2. 向mid索引值的左边扫描,与midVal一样就把下标存到ArrayListint temp = mid - 1;while(temp >= 0 && arr[temp] == findVal){arrayList.add(temp);temp--;}//3. 向mid索引值的右边扫描,与midVal一样就把下标存到ArrayListtemp = mid + 1;while (temp <= arr.length-1 && arr[temp] == findVal){arrayList.add(temp);temp++;}}//4.返回ArrayListreturn arrayList;}public static void main(String []args){int arr [] = {1,2,3,4,5,6,7,8,9,9,9};ArrayList<Integer> arrayList = binarySearch1(arr, 0, arr.length - 1, 9);System.out.println(arrayList.size());arrayList.forEach(System.out::println);}
}

3)插值查找(把二分查找的mid进行自适应优化)

分布不均匀的话不一定比折半好

package search;public class InsertValSearch {static int i = 1;public static int insertValSearch(int [] arr, int left, int right, int findVal){System.out.println("调用第" + i++ + "次");//注意findVal < arr[0] || findVal > arr[arr.length-1]必须有,否则mid可能会越界if (left > right || findVal < arr[0] || findVal > arr[arr.length-1]){return -1;}int mid = left + (right - left) * (findVal - arr[left]) / (arr[right] - arr[left]);int midVal = arr[mid];if (findVal > midVal){return insertValSearch(arr,mid + 1,right,findVal);}else if (findVal < midVal){return insertValSearch(arr,left,mid - 1,findVal);}else {return mid;}}public static void main(String[] args) {int [] arr = new int[100];//int [] arr1 = {1, 8, 10, 89, 1000, 1234};for (int i = 0; i < 100; i++) {arr[i] = i + 1;}int index = insertValSearch(arr, 0, arr.length - 1, 80);System.out.println("index = "+ index);//System.out.println(Arrays.toString(arr));}
}

4)斐波那契查找(黄金分割法1:1.618)



对于斐波那契数列:1、1、2、3、5、8、13、21、34、55、89……,前后两个数字的比值随着数列的增加,越来越接近黄金比值0.618。比如这里的89,把它想象成整个有序表的元素个数,而89是由前面的两个斐波那契数34和55相加之后的和,也就是说把元素个数为89的有序表分成由前55个数据元素组成的前半段和由后34个数据元素组成的后半段,那么前半段元素个数和整个有序表长度的比值就接近黄金比值0.618,假如要查找的元素在前半段,那么继续按照斐波那契数列来看,55 = 34 + 21,所以继续把前半段分成前34个数据元素的前半段和后21个元素的后半段,继续查找,如此反复,直到查找成功或失败,这样就把斐波那契数列应用到查找算法中了。

package search;import java.util.Arrays;public class FibonagucciSearch {//因为后面我们mid=low+F(k-1)-1,需要使用到斐波那契数列,因此我们需要先获取到一个斐波那契数列//非递归方法得到一个斐波那契数列public static int maxSize = 20;public static int[] fib() {int[] f = new int[maxSize];f[0] = 1;f[1] = 1;for (int i = 2; i < maxSize; i++) {f[i] = f[i - 1] + f[i - 2];}return f;}//编写斐波那契查找算法//使用非递归方式编写算法/*** @param a 数组* @param key key 我们需要查找的关键码(值)* @return 返回对应下标,没找到返回-1*/public static int fibonagucciSearch(int[] a, int key) {int low = 0;int high = a.length - 1;int k = 0; //表示斐波那契分割数值的下标,找到k很重要int mid = 0; //存放mid值int[] f = fib();//获取到斐波那契数列//获取到斐波那契数列分割数值的下标k//首先要明确:如果一个有序表的元素个数为n,并且n正好是(某个斐波那契数 - 1),即n=F[k]-1时,才能用斐波那契查找法。 如果有序表的元素个n不等于(某个斐波那契数 - 1),即n≠F[k]-1,这时必须要将有序表的元素扩展到大于n的那个斐波那契数 - 1才行,这段代码:while (high >= f[k] - 1) {//这里或者用 high+1 > f[k] - 1k++;}//因为f[k] 值 可能大于a的长度,因此我们需要使用Arrays类,构造一个新的数组并指向temp[]//不足的部分会使用0填充int[] temp = Arrays.copyOf(a, f[k]);//实际上需要使用a数组的最后的数填充temp//举例://temp = {1,8,10,89,1000,1234,0,0} => {1,8,10,89,1000,1234,1234,1234}for (int i = high + 1; i < f[k] - 1; i++) {temp[i] = a[high];}//使用while循环来处理,找到我们的数keywhile (low <= high) { //只要这个条件满足就可以找mid = low + f[k - 1] - 1;if (key < temp[mid]){ //我们应该继续向数组的前面查找(左边)high = mid -1;//为什么是k--//1.全部元素 = 前面的元素 + 后边的元素//2.f[k] = f[k-1]+f[k-2]//因为前面有f[k-1]个元素,所以我们可以继续拆分f[k-1] = f[k-2] + f[k-3]//即在f[k-1] 的前面继续查找 k--//即下次循环mid = f[k-1-1]-1k--;}else if (key > temp[mid]){我们应该继续向数组的后面查找(右边)low = mid +1;//为什么是k-2//说明//1.全部元素 = 前面的元素 + 后边的元素//2.f[k] = f[k-1]+f[k-2]//3.后面我们有f[k-2] 所以我们可以继续拆分f[k-2] = f[k-3] + f[k-4]//4.即在f[k-2] 的前面进行查找k-=2//5.即下次循环mid = f[k-1-2]-1k -= 2;}else {//找到//需要确定返回的是哪个下标if (mid <= high){return mid;}else {return high;}}}return -1;}public static void main(String[] args) {int[] arr = {1, 8, 10, 89, 1000,1234};System.out.println(fibonagucciSearch(arr,10));}
}

查找算法-(顺序查找、二分查找、插值查找、斐波那契查找)相关推荐

  1. 顺序,二分,插值,斐波那契 查找算法

    总结: 博客详细描述:(http://www.cnblogs.com/maybe2030/p/4715035.html#_label4) 关注: 二分查找.插值查找以及斐波那契查找都可以归为一类插值查 ...

  2. 斐波那契查找算法解析

    文章目录 前言 一.斐波那契数列 二.斐波那契查找算法 前言 学数据结构的时候被斐波那契查找算法困扰,刚开始难以理解,脑袋有点懵,翻看了许多大佬的博文,加上自己的理解发了出来 一.斐波那契数列 我们先 ...

  3. 斐波那契查找(黄金分割法)超详细详解

    斐波那契查找思路 说句实在话,这个斐波那契查找我看了不下5遍才理解他的思路和代码,因为它里面的值太多,不好理解容易绕晕,所以我给大家用自己的理解讲一下 什么是斐波那契 要想学会斐波那契查找,首先你得知 ...

  4. 理论基础 —— 查找 —— 斐波那契查找

    [概述] 斐波那契查找,其利用了黄金分割原理来对二分查找进行了改进. 黄金分割又称黄金比例,是指事物各部分间一定的数学比例关系,即将整体一分为二,较大部分与较小部分之比等于整体与较大部分之比,其比值约 ...

  5. 【Java数据结构与算法】第九章 顺序查找、二分查找、插值查找和斐波那契查找

    第九章 顺序查找.二分查找.插值查找和斐波那契查找 文章目录 第九章 顺序查找.二分查找.插值查找和斐波那契查找 一.顺序查找 1.基本介绍 2.代码实现 二.二分查找 1.基本介绍 2.代码实现 三 ...

  6. 算法:静态查找表(Static Search Table)(顺序查找、二分查找、插值查找、斐波纳契查找)

    转载 BinarySearch.java /*** @ClassName BinarySearch* @Description 折半查找** 可以使用插值公式将折半查找性能优化** 只需将其中的 mi ...

  7. Java数据结构之二分查找/插值查找/斐波那契查找

    目录 一.简单的线性查找 1.问题引出 2.代码实现 二.二分查找算法 1.基本介绍 2.代码实现(递归) 3.代码实现(非递归) 4.二分查找的功能完善 三.插值查找 1.简单介绍 2.代码实现(递 ...

  8. 【数据结构与算法】插值查找算法、斐波那契查找算法(黄金分割法)的介绍和程序实现

    目录 1. 插值查找算法 1.1 插值查找算法的介绍 1.2 插值查找算法的程序实现 2. 斐波那契查找算法 2.1 斐波那契查找算法的介绍 2.2 斐波那契查找算法的程序实现 1. 插值查找算法 1 ...

  9. Java有序表查找:折半查找、二分查找、差值查找和斐波那契查找

    Java有序表查找:折半查找.二分查找.差值查找和斐波那契查找     [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/51 ...

最新文章

  1. ipython notebook使用
  2. [转]C++基础:C++的结构struct
  3. 章节之外:makefile中的函数定义
  4. JVM GC性能方面的考虑(吞吐量和STW)
  5. TorchMetrics:PyTorch的指标度量库
  6. LeetCode 287. 寻找重复数(BitMap)
  7. 计算机网络数据链路层检错编码 --- 循环冗余码CRC
  8. php mysql-proxy报错_MySQL-proxy代理导致PHP PDO::ATTR_EMULATE_PREPARES的预处理出错,MySQL报General error: 1243错误...
  9. Myeclipse学习总结(2)——MyEclipse快捷键大全
  10. [转载]QMessageBox 用法_vortex_新浪博客
  11. oracle执行带有nbsp参数,Oracleamp;nbsp;参数文件amp;nbsp;spfileamp;nbsp;a
  12. ie下的firebug
  13. Hadoop:Hadoop单机伪分布式的安装和配置
  14. Java排序算法——选择排序(Selection Sort)
  15. java编程手册_java编程手册下载
  16. SCRUM浅谈,User Story,Sprint,Burn Down Chart
  17. ActivitiUFLO2Snaker流程引擎对比分析
  18. 蝌蚪在线匿名聊天室HTML源码
  19. Sitecore 8.2 防火墙规则的权威指南
  20. QIIME 2:可重复、交互和扩展的微生物组数据分析流程

热门文章

  1. O-C相关-08-动态类型与静态类型
  2. 740. Delete and Earn
  3. [hackinglab][CTF][注入关][2020] hackinglab 注入关 writeup
  4. [Leedcode][JAVA][面试题 08.11][硬币][动态规划]
  5. Codeforce Flea CodeForces - 32C 规律|思维
  6. HDOJ-1257 最少拦截系统
  7. 武大计算机专业湖北录取分数线,武汉大学2020年本科一批分专业录取分数统计(湖北省)...
  8. 增加数据_咱晋城人口又增加了?最新数据来了
  9. bootstrap带有下拉按钮的输入框_关于bootstrap--表单(下拉select、输入框input、文本域textare复选框checkbox和单选按钮radio)...
  10. python目标识别代码_利用ImageAI库只需几行python代码超简实现目标检测