Python查找算法之插补查找算法的实现
作者:Amo Xiang 发布时间:2021-03-12 08:16:57
一、插补查找算法
插补查找算法又称为插值查找,它是折半查找算法的改进版。插补查找是按照数据的分布,利用公式预测键值所在的位置,快速缩小键值所在序列的范围,慢慢逼近,直到查找到数据为止。根据描述来看,插值查找类似于平常查英文字典的方法。例如,在查一个以字母 D 开头的英文单词时,决不会用折半查找法。根据英文词典的查找顺序可知,D 开头的单词应该在字典较前的部分,因此可以从字典前部的某处开始查找。键值的索引计算,公式如下:
middle=left+(target-data[left])/(data[right]-data[left])*(right-left)
参数说明:
middle:所求的边界索引。
left:最左侧数据的索引。
target:键值(目标数据)。
data[left]:最左侧数据值。
data[right]:最右侧数据值。
right:最右侧数据的索引。
例如,已经有排序好的数列:34、53、57、68、72、81、89、93、99。要查找的数据是 53,使用插补查找法步骤如下:
步骤1:将数据列出来并利用公式找到边界值,计算过程如下:
将各项数据带入公式:
将数据取整,因此所求索引是 2,对应的数据是 57,将查找目标数据 53 与 57 进行比较,如下图所示。
步骤2:将 53 与 57 进行比较,结果是 53 小于 57,所以查找 57 的左半边数据,不用考虑右半边的数据,索引范围缩小到 0 和 2 之间,公式带入:
取整之后索引是 1,对应的数据是 53,将查找目标数据 53 与 53 进行比较,如下图所示:
步骤3:将 53 与 53 进行比较,所得结果相等,查找完成。说明:如果多次分割之后没有找到相等的值,表示这个键值没有在这个数列中。
通过上述的步骤1就能看出,插补查找算法比折半查找算法的取值范围更小,因此它的速度要比折半法查找快,这就是插补查找算法的优点。
二、实例:利用插补查找用户输入的数据
用户可以随意输入一组数据,例如本实例输入一组数据:34、53、57、68、72、81、89、93、99。在这组数据中用插补查找法分别查找数据 57、53、93、89、100,且显示每次查找的过程。用 Python 代码实现此过程,具体代码如下:
def insert_search(data, num):
"""
自定义查找函数:该函数使用的是插补查找算法
:param data: 原数列data
:param num: 键值num
:return:
"""
# 计算
left_index = 0 # 最左侧数据的索引
right_index = len(data) - 1 # 最右侧数据的索引
print("正在查找.......") # 提示
while left_index <= right_index:
# 使用公式计算出索引值
middle = left_index + (num - data[left_index]) / (data[right_index] - data[left_index]) * (
right_index - left_index)
# 取整
middle = int(middle)
# print(middle)
if num == data[middle]:
return middle # 如果键值等于边界值,返回边界位置
elif num < data[middle]:
# 输出位置在数列中的左半边
print(f"{num} 介于位置{left_index + 1}[{data[left_index]}]和边界值{middle + 1}[{data[middle]}]之间,找左半边......")
right_index = middle - 1 # 如果键值小于边界值,最右边数据索引等于边界位置减1
else:
# 输出位置在数列中的左半边
print(f"{num} 介于位置{middle + 1}[{data[middle]}]和边界值{right_index + 1}[{data[right_index]}]之间,找右半边......")
left_index = middle + 1 # 如果键值大于边界值,最左边数据索引等于边界位置加1
return -1 # 自定义函数到此结束
inp_num = 0 # 定义变量,用来输入键值
num_list = [34, 53, 57, 68, 72, 81, 89, 93, 99] # 定义数列
print("数据内容是:")
for index, ele in enumerate(num_list):
print(f" {index + 1}[{ele}]", end="") # 输出数列
print("")
flag = True # 开关,用来管控是否多次查找
while flag: # 循环查找
inp_num = int(input("请输入要查找的键值:").strip()) # 输入查找键值
result = insert_search(num_list, inp_num) # 调用自定义的查找函数——insert_search()函数
if result == -1: # 判断查找结果是否是-1
print(f"没有找到[{inp_num}]") # 若为-1,提示没有找到值
else:
# 若不为-1,提示查找位置
print(f"在{result + 1}个位置找到[{inp_num}]")
char = input("本次查找结束,是否继续查找,请输入 y(Y) 或 n(N):").strip()
if char.upper() == "N":
flag = False
程序执行结果如下图所示:
来源:https://blog.csdn.net/xw1680/article/details/115406312


猜你喜欢
- 打印类的所有属性和方法利用dir(obj)方法获得obj对象的所有属性和方法名,返回一个list。for item in dir(top_k
- 本文实例讲述了Python socket套接字实现C/S模式远程命令执行功能。分享给大家供大家参考,具体如下:一. 前言要求: 使用pyth
- 我就废话不多说了,直接上代码吧!#2.14from turtle import *from time import sleepdef go_
- 1. OpenCV:模板匹配。 获得小跳棋中心位置2.
- rs.open语句详细说明rs.Open [第一个参数],  
- 场景:把一个时间字符串转成Date,存进Mysql。时间天数会比实际时间少1天,也可能是小时少了13-14小时Mysql的时区是CST(使用
- 1.场景描述我们公司是做电商的,运营的工作指标都是按周来定的,所以他们对周特别敏感,希望我们能在日期选择器上显示周数。刚接到这个需求时,心中
- 每每见到这三个函数,我都会很懵,一定要到网上搜搜;今天,恰巧又见到了它们,所以想必是时候为它们做个笔记啦1.slice(数组)用法:arra
- 在开始部分,请看官非常非常耐心地阅读下面几个枯燥的术语解释,本来这不符合本教程的风格,但是,请看官谅解,因为列位将来一定要阅读枯燥的东西的。
- 读取问题如下所示,我们在文本中写了一个问题,然后将其读取出来。“黄河远上白云间,一片孤城万仞山。”的作者是谁?王之涣李白白居易杜甫file
- --查询 SELECT tp.tp_id, tp.tpmc, tp.leveid, tp.tpdz, tp.jgm, tp.scsj, tp
- 一 接口介绍如果说gorountine和channel是支撑起Go语言的并发模型的基石,让Go语言在如今集群化与多核化的时代成为一道亮丽的风
- 前言我们写好的gin项目想要部署在服务器上,我们应该怎么做呢,接下来我会详细的讲解一下部署教程。1.首先我们要有一台虚拟机,虚拟机上安装好g
- 一、基本介绍在编程中,程序员会经常使用到日期相关的函数,比如:统计某段代码执行花费的时间等等。在 Go 中,开发者为我们提供了 time 包
- javascript实现翻页效果:<html> <head> <title>上下翻页看 - aspxho
- 使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载刷新整个页面,这使得程序能够更快地回应用户的操作,如下笔记将简单介
- 一.错误分类1. 语法错误也称为解析错误,发生在传统编程语言的编译时,在JavaScript中发生在解释时,这些错误是由代码中的意外字符直接
- 小程序miniso的一个发布内容截图功能,话不多,先上代码wxml文件:<view class="cut-1-1 t-c {
- 注:答案一般在网上都能够找到。1.对if __name__ == 'main'的理解陈述2.python是如何进行内存管理的
- 之前整理发表了《XMLHTTPRequest的属性和方法简介》,它ajax要使用的核心的技术之一,现在就来实际运用它。这个Ajax标签导航,