21天学习挑战:经典算法---折半查找

134 阅读7分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情

算法概念

任何被明确定义的计算过程可以称作算法,它将某个值活一组值作为输入,并产生莫格值或一组值作为输出。所以算法可以被称作将输入转为输出的一系列的计算步骤。

这样的概况是比较抽象和标准的,其实说白了就是步骤明确的解决问题的方法。由于是在计算机中执行,所以通常先用伪代码表示,清晰的表达出思路和步骤。这样真正执行的时候,就可以使用不同的语言来实现出相同的兄啊过给。

概况的说,算法就是解决问题的工具。在描述一个算法时,我们关注的是输入与输出。也就是说只要把原始数据和结果描述清楚了,那么算法所作的事情也就清楚了。

在设计一个算法时也是需要先明确我们有什么和我们要什么。

在这里插入图片描述

相关概念

数据结构

算法经常会和数据结构一起出现,这是因为对于同一个问题,使用不同的数据结构来存储数据,对应的算法可能千差万别。 所以在整个学习过程中,也会涉及到各种数据结构的使用 常见的数据结构包括:

  • 数组
  • 队列
  • 链表
  • 树等等

算法的效率

在一个算法设计完成后,还需要对算法的执行情况作一个评估。一个好的算法,可以大幅度的节省资源消耗和时间。在进行评估时不需要太具体,毕竟数据量是不确定的,通常是以数据量为基准确定一个量级。

通常会使用到两个概念:

  • 时间复杂度
  • 空间复杂度

时间复杂度

通常把算法中的基本操作重复执行的频度称为算法的时间复杂度。算法中的基本操作一般是指算法中最深层循环内的语句(赋值、判断、四则运算等基础操作)。我们可以把时间频度记为T(n),它与算法中语句的执行次数成正比。其中的n被称为问题的规模,大多数情况下为输入的数据量。

对于每一段代码,都可以转为常数或者与n相关的函数表达式,记作f(n)。如果我们把每一段代码的花费的时间加起来就能够得到一个刻画时间复杂度的表达式,在合并后保留量级最大的部分即可确定时间复杂度。

空间复杂度

程序从开始执行到结束所需要的内存量。也就是整个代码中最大需要占用多少的空间。为了评估算法本身,输入数据所占用的空间不会考虑,通常更关注运算时需要额外定义多少临时变量或多少存储结构。

元素查找介绍

查找也被称为检索,算法的主要目的是在某种数据结构中,找出满足给定条件的元素(以等值匹配为例)。如果找打满足条件的元素,则代表查找成功,否则查找失败。 在进行查找时,对于不同的数据结构以及元素集合状态,会有相对匹配的算法,在使用时也需要注意算法的前置条件。在元素查找相关文章中只讨论数据元素只有一个数据项的情况,即关键字(key)就是对应数据元素的值,对应到具体的数据结构,可以理解为一维数组。

  • 顺序查找 也称为线性查找,是最简单的查找方法。思路也很简单,从数组的一边开始,逐个进行元素的比较,如果与给定的待查找元素相同,则查找成功,如果整个扫描结束后,仍未找到相匹配的元素,则查找失败。

  • 折半查找 也称为二分查找,是一种效率相对较高的查找方法。使用该算法的前提要求是,元素已经有序,因为算法的核心思想是尽快的缩小搜索区间,这就需要保证在缩小范围的同时,不能有元素的遗漏。

  • 索引查找 索引查找主要分为基本索引查找和分块查找,核心思想是对于无序的数据集合,先建立索引表,使得索引表有序或分块有序,结合顺序查找与索引查找的方法,完成查找。

折半查找

元素查找介绍

查找也被称为检索,算法的主要目的是在某种数据结构中,找出满足给定条件的元素(以等值匹配为例)。如果找打满足条件的元素,则代表查找成功,否则查找失败。 在进行查找时,对于不同的数据结构以及元素集合状态,会有相对匹配的算法,在使用时也需要注意算法的前置条件。在元素查找相关文章中只讨论数据元素只有一个数据项的情况,即关键字(key)就是对应数据元素的值,对应到具体的数据结构,可以理解为一维数组。

  • 顺序查找 也称为线性查找,是最简单的查找方法。思路也很简单,从数组的一边开始,逐个进行元素的比较,如果与给定的待查找元素相同,则查找成功,如果整个扫描结束后,仍未找到相匹配的元素,则查找失败。

  • 折半查找 也称为二分查找,是一种效率相对较高的查找方法。使用该算法的前提要求是,元素已经有序,因为算法的核心思想是尽快的缩小搜索区间,这就需要保证在缩小范围的同时,不能有元素的遗漏。

  • 索引查找 索引查找主要分为基本索引查找和分块查找,核心思想是对于无序的数据集合,先建立索引表,使得索引表有序或分块有序,结合顺序查找与索引查找的方法,完成查找。

折半查找

  • 输入 n个数的有序序列,以数组为例,默认升序。 待查找元素key

  • 输出 查找成功:返回元素所在位置编号 查找失败:返回-1或自定义失败标识

  • 算法说明 算法的核心思想是:不断的缩小搜索范围,每次取区间的中心来进行比较,会有三种情况发生 1 与key相等:直接返回对应的位置 2 比key大:由于元素有序,要查找的元素一定在左侧(如有),于是搜索区间变为左一半 3 比key小:由于元素有序,要查找的元素一定在右侧(如有),于是搜索区间变为右一半

于是,只要不断重复取中间比较和指定新的搜索区间这两个步骤,直到区间的两个端点已经重合(代表搜索完毕)或者找到元素时为止。

  • 算法流程 查找关键字为7的元素: 在这里插入图片描述 第1次比较:mid坐标为4,对应元素为10,大于7,则区间变为左一半:[0,3] 第2次比较:mid坐标为1,对应元素为1,小于7,则区间变为右一半:[2,3] 第3次比较:mid坐标为2,对应元素为7,等于7,返回逻辑序号:mid+1 = 3

伪代码

折半查找需要不断的改变区间和取中间元素进行判断,只要明确key与比较元素的关系就可以确定新的比较区间,然后循环整个过程。 伪代码表示如下:

left = 1
right = A.length
while left <= right
	mid = (left+right)/2
	if A[mid] == key
		return mid
	else if A[mid]>key
		right = mid - 1
	else
	 	left = mid - 1
return -1