博客
关于我
查找算法:二分法,插值法的公式详解——菜鸟进阶的必经之路!!!
阅读量:337 次
发布时间:2019-03-04

本文共 2725 字,大约阅读时间需要 9 分钟。

@查找算法:二分法与插值的详细分析

1、简单的二分法查找


1.1、算法分析

       二分法,顾名思义,就是对其进行折半分别在两边查找。两边再分别进行折半、查找,再折半、再查找,直到找到为止,或者整个数组都找不到这个值,应立即结束查找。

1.2、画图分析

在这里插入图片描述

1.3、代码实现1:递归法

/**	 * 	 * @param arr 查询的数组	 * @param value 查询的值	 * @return 查询到的值的索引	 */	public static int ef(int arr[], int value) {   		int left = 0;		int right = arr.length - 1;		int mid = 0;		while (left <= right) {   						mid = (left + right) >> 1;			if (value > arr[mid]) {   				left = mid + 1;			} else if (value < arr[mid]) {   				right = mid - 1;			} else {   				return mid;			}		}		return -1;	}

1.3、代码实现2:循环法

/**	 * 	 * @param arr 查询的数组	 * @param value 查询的值	 * @return 查询到的值的索引	 */	public static int ef(int arr[], int value) {   		int left = 0;		int right = arr.length - 1;		int mid = 0;		while (left <= right) {   						mid = (left + right) >> 1;			if (value > arr[mid]) {   				left = mid + 1;			} else if (value < arr[mid]) {   				right = mid - 1;			} else {   				return mid;			}		}		return -1;	}

2、二分微改版:插值查找


2.1、算法分析

       相比于二分法的折半,插值就相当于折插值数,至于什么是折插值数,我们需要先了解一下它的公式:

  • 二分法:mid = (left + right) >> 1 (较简单,就不做过多的介绍了!!)
  • *插值法:mid = left + (value-arr[left]) * (right - left) / (arr[right] - arr[left])
  • 首先,在使用插值法之前,我们需要先了解插值法的 使用条件:必须是一个已排序的数组,这一点和二分法一样,但如果要体现其价值,则必须是一个已排序的连续分布均匀的数组,因为在这样的数组中,无论查哪一个元素,都只用一次就能查询到这个值。至于为什么只用了一次,我们还得回到其公式上面,为了便于理解,先假设有一个连续分布均匀的数组,接下来的说明皆围绕该例子
                                                                arr[] = {1,2,3,4,5,6};
    对于插值法的公式,我们根据其条件可以发现 (right - left) => (arr[right] - arr[left]),因为连续分布的特性,索引和元素的差值是成正比的, 如果连续分布的元素差值为1,则可以发现(right - left) =(arr[right] - arr[left]),所以,根据其正比例的关系,我们可以将公式化简为 : mid = left + value - arr[left],这样一来,我们就能很清晰的观察其规律了,left为左边界,value - arr[left]的结果为left到value索引处元素的差值, 以arr为例,假设我们要查找3这个元素,那么套用公式就是 mid = 0 + 3 - 1 = 2,而arr[2]刚好等于3,注意,上面的化简公式只是为了方便理解而推论的,只适用于连续排列差值为1的数组,对于其他分布的数组并不适用,还是用插值法的公式,对于其他分布的数组来说, (right - left) / (arr[right] - arr[left])的值就是该数组的分布比例, (value-arr[left]) 是要查找的值与左边界的差值,用该差值/分布比例,就能得到要查找的值value的索引,再用该索引 - 左边界,得到的值就是要查找的值的索引。

  • 公式总结:mid = left + (value-arr[left]) * (right - left) / (arr[right] - arr[left])
    • (right - left) / (arr[right] - arr[left]):数组的比例关系
    • (value-arr[left]):左边界元素(相当于0)到value的元素差值(通俗说就是从0到查找处元素的差值)
    • left:当前的左边界(并非一直为0,如果一次查找不到左边界响应也会发生变化)

2.2、额,这个图就不画了,和二分差不多

2.3、代码实现(递归法,循环请参考二分法的思路):

public static int insertValSearch(int arr[],int left,int right,int value) {   		if(left>right ) {   			return -1;		}		System.out.println("aaa");				//自适应:如果是一个连续的有序数组,那么可以自适应,只需要一次能查到		//如果是一个非连续的有序数组,那么只能适应两端,两端之内的值则和二分一样		int mid = left + (right-left)*(value-arr[left])/(arr[right]-arr[left]);//		System.out.println(mid);//		int mid = left + value - arr[left];		System.out.println(mid);		if(value>arr[mid]) {   			return insertValSearch(arr, mid+1, right, value);		}else if(value

3、总结

        越努力,越幸运,The harder you work, the more luck you have.

        关注笔笔一起努力吧ヾ(◍°∇°◍)ノ゙!!!

转载地址:http://gcrq.baihongyu.com/

你可能感兴趣的文章
MySQL中UPDATE语句的神奇技巧,让你操作数据库如虎添翼!
查看>>
Mysql中varchar类型数字排序不对踩坑记录
查看>>
MySQL中一条SQL语句到底是如何执行的呢?
查看>>
MySQL中你必须知道的10件事,1.5万字!
查看>>
MySQL中使用IN()查询到底走不走索引?
查看>>
Mysql中使用存储过程插入decimal和时间数据递增的模拟数据
查看>>
MySql中关于geometry类型的数据_空的时候如何插入处理_需用null_空字符串插入会报错_Cannot get geometry object from dat---MySql工作笔记003
查看>>
mysql中出现Incorrect DECIMAL value: '0' for column '' at row -1错误解决方案
查看>>
mysql中出现Unit mysql.service could not be found 的解决方法
查看>>
mysql中出现update-alternatives: 错误: 候选项路径 /etc/mysql/mysql.cnf 不存在 dpkg: 处理软件包 mysql-server-8.0的解决方法(全)
查看>>
Mysql中各类锁的机制图文详细解析(全)
查看>>
MySQL中地理位置数据扩展geometry的使用心得
查看>>
Mysql中存储引擎简介、修改、查询、选择
查看>>
Mysql中存储过程、存储函数、自定义函数、变量、流程控制语句、光标/游标、定义条件和处理程序的使用示例
查看>>
mysql中实现rownum,对结果进行排序
查看>>
mysql中对于数据库的基本操作
查看>>
Mysql中常用函数的使用示例
查看>>
MySql中怎样使用case-when实现判断查询结果返回
查看>>
Mysql中怎样使用update更新某列的数据减去指定值
查看>>
Mysql中怎样设置指定ip远程访问连接
查看>>