在java中,常用的查找有四种

  1. 顺序(线性)查找
  2. 二分查找折半查找
  3. 插值查找
  4. 斐波那契查找

目录

  • 1. 线性查找
  • 2. 二分查找
  • 3. 插值查找
  • 4. 斐波那契查找

1. 线性查找

线性查找是逐一比对,发现有相同值,就返回下标

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

2. 二分查找

使用二分查找算法的前提是序列有序

public static int binarySearch(int[] arr, int left, int right, int findVal) {if (left > right)//递归结束return -1;int mid = (left + right) / 2;int midVal = arr[mid];if (findVal > midVal)return binarySearch(arr, mid + 1, right, findVal);//向右递归else if (findVal < midVal)return binarySearch(arr, left, mid - 1, findVal);//向左递归elsereturn mid;
}

问题:如果数组中有相同的元素,只会返回一个索引值


解决方案:找到mid索引时,不要马上返回,而是分别向左向右扫描所有满足查找值,假如到集合ArrayList中

public static ArrayList<Integer> binarySearch(int[] arr, int left, int right, int findVal) {if (left > right)//递归结束return new ArrayList<Integer>();int mid = (left + right) / 2;int midVal = arr[mid];if (findVal > midVal)return binarySearch(arr, mid + 1, right, findVal);//向右递归else if (findVal < midVal)return binarySearch(arr, left, mid - 1, findVal);//向左递归else {ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(mid);int temp_left = mid - 1;//向左扫描while (temp_left > 0 && arr[temp_left] == findVal) {arrayList.add(temp_left);temp_left--;}int temp_right = mid + 1;//向右扫描while (temp_right <= arr.length - 1 && arr[temp_right] == findVal) {arrayList.add(temp_right);temp_right++;}return arrayList;}
}

3. 插值查找

插值查找的前提也要求序列有序

public static int insertValueSearch(int[] arr, int left, int right, int findVal) {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 insertValueSearch(arr, mid + 1, right, findVal);//向右递归else if (findVal < midVal)return insertValueSearch(arr, left, mid - 1, findVal);//向左递归elsereturn mid;
}

插值查找注意事项

  1. 对于数据量较大,关键字分布比较均匀的查找表来说,采用插值查找,速度较快
  2. 关键字分布不均匀的情况下,该方法不一定比折半查找要好

4. 斐波那契查找

又称黄金分割法查找,也得满足序列有序

斐波那契查找原理与前两种相似,仅仅改变了中间结点mid的位置,mid不再是中间或插值得到,而是位于黄金分割点附近,即 mid=low+fib(k-1)-1(fib代表斐波那契数列

原理

  • 由斐波那契数列 fib[k]=fib[k-1]+fib[k-2] 的性质,可以得到fib[k]-1=(fib[k-1]-1)+(fib[k-2]-1)+1

    该式说明:只要顺序表的长度为fib[k]-1,则可以将该表分成长度为fib[k-1]-1fib[k-2]-1的两段,从而中间位置为mid=low+F(k-1)-1

  • 类似的,每一子段也可以用相同的方式分割

  • 但顺序表长度length不一定刚好等于F[k]-1,所以需要将原来的顺序表长度length增加至F[k]-1,新增的位置(从n+1到F[k]-1位置),都赋为n位置的值即可

    这里的k值只要能使得F[k]-1恰好大于或等于n即可;我们可以执行以下代码获得k的值

while(length>fib(k)-1)k++;
import java.util.Arrays;public class Test {public static void main(String[] args) {int[] arr = {1, 2, 4, 5, 19, 19, 80};int index = fibSearch(arr, 81);System.out.println(index);}//获取斐波拉契数列public static int[] fib() {int[] f = new int[20];f[0] = 1;f[1] = 1;for (int i = 2; i < 20; i++) {f[i] = f[i - 1] + f[i - 2];}return f;}public static int fibSearch(int[] arr, int findVal) {int left = 0;int right = arr.length - 1;int k = 0;//表示斐波那契数列分割数值的下标int mid;int[] fib = fib();//获得斐波那契数列//获取斐波那契数列分割数值的下标while (right > fib[k] - 1)k++;int[] temp = Arrays.copyOf(arr, fib[k]);//因为fib(k)的长度可能大于arr.length,因此需要构建一个新数组,不足的部分会用0填充for (int i = right + 1; i < temp.length; i++)//将不足的部分用数组的最后一个元素填充temp[i] = arr[right];while (left <= right) {mid = left + fib[k - 1] - 1;if (findVal < temp[mid]) {//向前查找right = mid - 1;//全部元素fib[k] = 前面的元素fib[k-1] + 后面的元素fib[k-2]//此时向前面的fib[k-1]个元素中查找,可以继续拆分fib[k-1]=fib[k-2]+fib[k-3]//即下次循环mid=fib[k-2]-1k--;} else if (findVal > temp[mid]) {//向后查找left = mid + 1;//全部元素fib[k] = 前面的元素fib[k-1] + 后面的元素fib[k-2]//此时向后面的fib[k-2]个元素中查找,可以继续拆分fib[k-2]=fib[k-3]+fib[k-4]//即下次循环mid=fib[k-3]-1k -= 2;} else {//找到了if (mid <= right)return mid;elsereturn right;}}return -1;//没找到}}

数据结构——四大查找算法(工作必备)相关推荐

  1. 【数据结构】查找算法

    文章目录 查找算法 顺序查找算法 折半查找 分块查找 二叉排序树 平衡二叉树(AVL树) 散列表 哈希函数的构造 处理冲突的方法 哈希查找算法及其实现 查找算法 查找:在数据集合中寻找满足某种条件的数 ...

  2. 数据结构之查找算法:顺序查找

    查找算法:顺序查找 思维导图: 顺序查找的定义: 顺序查找的代码实现: 顺序查找的性能: 思维导图: 顺序查找的定义: 顺序查找的代码实现: typedef struct { //查找表数据结构int ...

  3. 数据结构: 插值查找算法

    import java.util.Arrays;// 插值查找算法,也要求数组是有序的 public class InsertValueSearch {public static void main( ...

  4. 数据结构之查找算法:基本概念

    查找算法:基本概念 思维导图: 查找的基本概念及基本操作: 思维导图: 查找的基本概念及基本操作: ps: Pi表示元素出现的概率,一般情况下,默认各个元素出现的概率相同 Ci表示元素出现的次数

  5. 数据结构之查找算法:散列查找

    查找算法:散列查找 思维导图: 散列函数和散列表: 构造散列函数的要求: 构造散列函数的方法: 直接定址法: 除留取余法: 数字分析法: 平方取中法: 折叠法: 解决冲突的方法: 开放定址法: 线性探 ...

  6. 数据结构之查找算法:B+树

    查找算法:B+树 B+树的定义:(数据库中应用) B树与B+树的区别: B+树的定义:(数据库中应用) 例: ps:这是一颗四阶树,所以每个节点最多可以有4颗子树 ps:每个节点的关键字都不能小于2 ...

  7. 数据结构之查找算法:B树

    查找算法:B树 思维导图: B树的定义: 例: n个关键字,阶数为m,高度为h的B树的高度计算 基本操作: 查找: 插入: 删除: 对终端节点的删除: 对非终端节点的删除: 思维导图: B树的定义: ...

  8. 数据结构之查找算法:分块查找

    查找算法:分块查找 思维导图: 分块查找的定义: 如何分块: 如何查找: 代码实现: 查找效率: 思考: 思维导图: 分块查找的定义: 如何分块: 例: 如何查找: 1.先查找在哪块 2.然后查找块内 ...

  9. 数据结构之查找算法:折半查找

    查找算法:折半查找 思维导图: 算法思想: 代码实现: 判定树: 折半查找判定树的构造: 顺序查找与折半查找对比: 思维导图: 算法思想: 代码实现: typedef struct {int *ele ...

最新文章

  1. 手机发送验证码的业务逻辑探究-主要是安全性,响应性
  2. BZOJ3442: 学习小组
  3. code blocks无法输出中文解决方法
  4. 在Mac上如何管理添加,删除和延迟启动项
  5. php连接sql server
  6. python生成word目录_Python word_cloud导出字体路径后找不到字体路径
  7. 一文理解二元logistic回归
  8. From Fidelity to Perceptual Quality: A Semi-Supervised Approach for Low-Light Image Enhancement
  9. 计算机英语说明文,英语说明文
  10. 挂站服务器什么意思?挂站服务器可以挂多少网站?
  11. java基于ssm开发的多商家书店商城系统
  12. 嵌入式接口之TIM定时器与NVIC的STM32模板库函数的一些解释
  13. 使用NHibernate 3.2实现Repository(ORuM)(三)NHibernate、Mapping、Mapping-By-Code
  14. KY35 最简真分数
  15. 程序员:一个女生不主动联系你还有机会吗?
  16. 阿里国际站新版关键词你升级了吗?
  17. Oracle 表解锁
  18. 电池充放电自动测试系统介绍
  19. julia系列1:介绍与安装
  20. 金蝶K3服务器一键配置精灵

热门文章

  1. Gradle 将项目publish到Nexus,Kotlin将项目发布到nexus,springboot项目发布到maven仓库
  2. 快速给shell脚本加上使用提示
  3. python第三方库之学习pyserial库--串口通信
  4. 想让关系更好就不要怕麻烦
  5. debian10 简单的bash脚本监控apache运行状态
  6. 理解和实现分布式TensorFlow集群完整教程
  7. 安装win下的Anaconda ----针对python3.6.4版本
  8. AI中pass架构设计优化
  9. 芯片IP,SOC,FPGA智能卡
  10. 工艺技术:14nm与28nm工艺