本系列文章涉及的算法包括搜索、回溯、递归、排序、迭代、贪心、分治和动态规划等,涉及的数据结构包括字符串、列表、指针、区间、队列、矩阵、堆栈、链表、哈希表、线段树、二叉树、二叉搜索树和图结构等。
本系列文章是笔者为适应当前教育改革的创新要求,更好地践行语言类课程,满足实践教学与创新能力培养的需要,阅读大量书籍、各大互联网公司的面试算法、LintCode、LeetCode、九章算法和结合笔者近几年项目经验编写的系列文章,精选了 1000 个趣味性、实用性强的应用实例,从不同难度、不同算法、不同类型和不同数据结构等方面,将实际算法进行总结,希望为 Python 编程人员抛砖引玉。由于笔者经验与水平有限,博文中疏漏及不妥之处在所难免,衷心地希望各位读者在评论区多提宝贵意见及具体的修改建议,以便笔者进一步修改和完善。
分块查找是二分法查找和顺序查找的改进方法,分块查找要求索引表是有序的,对块内结点没有排序要求,块内结点可以是有序的也可以是无序的。
分块查找就是把一个大的线性表分解成若干块,每块中的节点可以任意存放,但块与块之间必须排序。与此同时,还要建立一个索引表,把每块中的最大值作为索引表的索引值,此索引表需要按块的顺序存放到一个辅助数组中。查找时,首先在索引表中进行查找,确定要找的结点所在的块。由于索引表是排序的,因此,对索引表的查找可以采用顺序查找或二分查找;然后,在相应的块中采用顺序查找,即可找到对应的结点。
例如,有这样一列数据:23、43、56、78、97、100、120、135、147、150。如下图所示:
想要查找的数据是 150,使用分块查找法步骤如下:
步骤1:将上图所示的数据进行分块,按照每块长度为 4 进行分块,分块情况如下图所示:
说明:每块的长度是任意指定的,博主在这里用的长度为4,读者可以根据自己的需要指定每块长度。
步骤2:选取各块中的最大关键字构成一个索引表,即选取上图所示的各块的最大值,第一块最大的值是 78,第二块最大的值是 135,第三块最大值是 155,形成的索引表如下图所示:
步骤3:用顺序查找或者二分查找判断想要查找数据 150 在上图所示的索引表中的哪块内容中,这里博主用的是二分查找法,即先取中间值 135 与 150 比较,如下图所示:
步骤4:结果是中间位置的数据 135 比目标数据 150 小,因此目标数据在 135 的下一块内。将数据定位在第 3 块内,此时将第 3 块内的数据取出,进行顺序比较,如下图所示:
步骤5:通过顺序查找第 3 块的内容,终于在第 9 个位置找到目标数,此时分块查找结束。
总结:至此,分块查找算法已经讲解完毕。通过和二分查找法和顺序查找法对比来看,分块查找的速度虽然不如二分查找算法,但比顺序查找算法快得多。当数据很多且块数很大时,对索引表可以采用二分查找,这样能够进一步提高查找的速度。
具体代码如下:
def search(data, key): # 用二分查找 想要查找的数据在哪块内
length = len(data) # 数据列表长度
first = 0 # 第一位数位置
last = length - 1 # 最后一个数据位置
print(f"长度:{length} 分块的数据是:{data}") # 输出分块情况
while first <= last:
mid = (last + first) // 2 # 取中间位置
if data[mid] > key: # 中间数据大于想要查的数据
last = mid - 1 # 将last的位置移到中间位置的前一位
elif data[mid] < key: # 中间数据小于想要查的数据
first = mid + 1 # 将first的位置移到中间位置的后一位
else:
return mid # 返回中间位置
return False
# 分块查找
def block(data, count, key): # 分块查找数据,data是列表,count是每块的长度,key是想要查找的数据
length = len(data) # 表示数据列表的长度
block_length = length // count # 一共分的几块
if count * block_length != length: # 每块长度乘以分块总数不等于数据总长度
block_length += 1 # 块数加1
print("一共分", block_length, "块") # 块的多少
print("分块情况如下:")
for block_i in range(block_length): # 遍历每块数据
block_data = [] # 每块数据初始化
for i in range(count): # 遍历每块数据的位置
if block_i * count + i >= length: # 每块长度要与数据长度比较,一旦大于数据长度
break # 就退出循环
block_data.append(data[block_i * count + i]) # 每块长度要累加上一块的长度
result = search(block_data, key) # 调用二分查找的值
if result != False: # 查找的结果不为False
return block_i * count + result # 就返回块中的索引位置
return False
data = [23, 43, 56, 78, 97, 100, 120, 135, 147, 150, 155] # 数据列表
result = block(data, 4, 150) # 第二个参数是块的长度,最后一个参数是要查找的元素
print("查找的值得索引位置是:", result) # 输出结果
运行结果如下图所示:
从上面的运行结果看到,当查找 150 时,查找结果完全符合上述描述的步骤。
感谢您阅读本篇博文,希望本文能成为您编程路上的领航者。祝您阅读愉快!
????好书不厌读百回,熟读课思子自知。而我想要成为全场最靓的仔,就必须坚持通过学习来获取更多知识,用知识改变命运,用博客见证成长,用行动证明我在努力。
????如果我的博客对你有帮助、如果你喜欢我的博客内容,请点赞
、评论
、收藏
一键三连哦!听说点赞的人运气不会太差,每一天都会元气满满呦!如果实在要白嫖的话,那祝你开心每一天,欢迎常来我博客看看。
?编码不易,大家的支持就是我坚持下去的动力。点赞后不要忘了关注
我哦!
前言 做一个新的项目就需要常用的代码,比如 登录,注册 (模板) 全局路由守卫(...
前言 在之前的博客里,笔者详细阐述了Prometheus数据的插入过程。但我们最常见的...
一、为何人工智能(AI)首选Python? 读完这篇文章你就知道了。我们看谷歌的Tensor...
ObjectvieSQL简介 ObjectiveSQL 是一个Java ORM 框架,它不仅是Active Record 模...
一、Postman背景介绍 用户在开发或者调试网络程序或者是网页B/S模式的程序的时候...
数据库SQLServer,测试程序显示出错信息:"ADODB.Recordset 错误 “800a0e78” ...
声明本文只作学习研究禁止用于非法用途否则后果自负如有侵权请告知删除谢谢 文章...
今天来看一下asp.net core的执行管道。先看下官方说明: 从上图可以抛光,asp.ne...
了解如何在 Bash 中编写定制程序以自动执行重复性操作任务。 Unix 最初的希望之...
文章目录 Java基础入门训练 一、根据年龄数值输出年龄段 二、打印1-100素数 三、...