分治算法(一)二分搜索技术
分治算法的本质就是将一个大规模的问题分解为若干个小规模的相同子问题,分而治之。
1.分治算法简述
1.1分治算法也有它的适用条件,满足以下3个条件,才能使用分治法来解决:
(1)原问题可分解为若干个规模较小的相同子问题
(2)子问题相互独立
(3)子问题的解可以合并为原问题的解
1.2使用分治法解题的步骤:
(1)分解:将要解决的问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题。
(2)治理:对子问题进行求解。
(3)合并:按原问题的要求,将子问题的解逐层合并构成原问题的解。
2.用二分搜索技术玩猜数字游戏
2.1问题描述
假如你女朋友想跟你玩一个游戏,说:“亲爱的,猜一下我心里想的是哪个数字?这个数字在1~10范围内。”你可能会猜1,女朋友说:“小了。”接着你猜2,女朋友说:“小了。”接着你又猜3,女朋友还是说:“小了。”这时候女朋友会很无奈地说:“天呐,你怎么可以这么笨!”这样每次加1的方法来猜,如果给定的数字是1,那么很幸运,一次就能猜中;但是如果给定的是10,用这种方法就需要猜10次。
推广开来,如果是n个数,使用这种方法最坏的情况要猜n次才能成功。如何能够用最少次数猜中给定的数字?我们的二分查找(也叫折半查找)可以很好地解决这个问题。就拿上面问题为例,因为这些数字(1到10)是有序(升序)的,使用二分查找每次和中间元素比较,如果提示说猜的数字比给定的数字小了,即给定数字比中间元素大,则在后半部分查找;如果提示说猜的数字比给定的数字大了,即给定数字比中间元素小,则在前半部分查找。这样每次查找,问题都会缩小为上次问题规模的一半,所以也被称为折半查找。
2.2算法设计
用列表num[]存储该有序序列(假定为升序),设变量low表示查找范围的下界,high表示查找范围的上界,middle表示查找范围的中间位置,x为特定的查找元素。
(1)初始化。令low=0,即指向有序列表num[]的第一个元素(列表元素下标从0开始);high=n-1,即指向有序列表num[]的最后一个元素,n表示列表长度,也就是列表元素的个数。
(2)middle=(low+high)/ 2,即指向查找范围的中间元素。(low+high)为奇数的话,除以2并不能得到整数,但是列表中元素的下标都是整数,这里实际上是向下取整,比如:3.5向下取整为3。
(3)判定 low<=high 是否成立,如果成立,转第4步,否则,说明该列表中没有指定元素,算法结束。
(4)判断 x 与 num[middle] 的关系。如果 x=num[middle],搜索成功,算法结束;如果 x>num[middle],令 low=middle+1;如果 x<num[middle],令 high=middle-1,转为第2步。
2.3算法实现
(1)非递归实现
numList = []
#定义一个计数变量,统计查找次数
count = 1 def BinarySearch(numList,x):low = 0high = len(numList) - 1global countwhile(low <= high):#地板除向下取整middle = (low + high) // 2if x == numList[middle]:#指定元素等于中间元素,查找成功,返回元素下标return middleelif x < numList[middle]:#指定元素小于中间元素,到前半部分查找high = middle - 1count = count + 1else:#指定元素大于中间元素,到后半部分查找low = middle + 1count = count + 1return Nonen = int(input('请输入数列中的元素个数n为:'))
for i in range(n):number = int(input('请依次输入数列中的元素:'))numList.append(number)# 列表的sort函数,默认为升序
numList.sort()
print('升序排序后的列表为:',numList)
x = int(input('请输入要查找的元素:'))
index = BinarySearch(numList,x)
print('共查找了',count,'次!')
if index == None:print('该列表中没有要查找的元素!')
else:print('要查找的元素:',x,',在列表中的位置为:',index+1)
测试:
请输入数列中的元素个数n为:7
请依次输入数列中的元素:16
请依次输入数列中的元素:30
请依次输入数列中的元素:22
请依次输入数列中的元素:31
请依次输入数列中的元素:63
请依次输入数列中的元素:12
请依次输入数列中的元素:56
升序排序后的列表为: [12, 16, 22, 30, 31, 56, 63]
请输入要查找的元素:16
共查找了 2 次!
要查找的元素: 16 ,在列表中的位置为: 2
(2)递归实现
def recusionBS(numList,x,low,high):if low > high:return Nonemiddle = (low + high) // 2if x == numList[middle]:return middleelif x < numList[middle]:return recusionBS(numList,x,low,middle-1)else:return recusionBS(numList,x,middle+1,high)index = recusionBS([1,2,3,4,5],2,0,4)
print('要查找的元素下标是:',index)
测试:
要查找的元素下标是: 1
分治算法(一)二分搜索技术相关推荐
- Leetcode快速入门之第三节课: 分治算法
文章目录 1. 算法引入 2. 分治算法之归并排序 2.1 88题:合并两个有序数组 3. 分治算法之快速排序 3.1 Leetcode 215 Kth Largest Element in an A ...
- 五大常用算法——分治算法详解及经典例题
一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子 ...
- 五大常用算法之一:分治算法
分治算法 一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题-- ...
- 一篇文章了解分治算法
分治算法 一.基本概念 二.基本思想及策略 三.分治法适用的情况 四.分治法的基本步骤 五.分治法的复杂性分析 六.可使用分治法求解的一些经典问题 七.依据分治法设计程序时的思维过程 一.基本概念 在 ...
- 三十三、分治算法---汉诺塔问题
一.分治算法的介绍 分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或 相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以 ...
- 「五大常用算法」一文图解分治算法和思想
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 前言 分 ...
- 算法导论系列:分治算法
说起分治法,大家一定也都听过秦始皇采用郡县制将国家分为三十六郡的故事,我们常说"山高皇帝远",意思就是山高路远,皇帝都管不了,实际上无论皇帝多远,山有多高,整个国家都属于朝廷统治, ...
- 【数据结构与算法】【算法思想】分治算法
贪心算法 回溯算法 分治算法 动态规划 MapReduce本质就是分治算法,是Google大数据处理的三驾马车之一,另外两个是GFS和Bigtable.它在倒排索引,PageRank计算,网页分析等搜 ...
- 分治算法兵乓球比赛日程(java)
分治算法之兵乓球比赛日程 分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同.求出子问题的解,就可得到原问题的解.也就是字面上的解释是" ...
最新文章
- 济南python工资一般多少钱-马哥教育官网-专业Linux培训班,Python培训机构
- ArrayList、LinkedList、Vector的区别。
- 【数学基础】运筹学:拉格朗日乘子法和KKT条件(上)
- linux下删除乱码文件名的方法
- Vue.js 第1章 Vue常用指令学习
- memcache使用方法测试
- Non-ASCII character \xe6 in file
- 图解:Kafka 水印备份机制
- 简述python的优点_Python是什么及Python的优点和缺点
- 重载 重载递增递和减运算符
- (转)老男孩教育每日一题-汇总博客
- android 滤镜录制,Android Camera 实时滤镜
- HTML+CSS淘宝首页[web课设代码+模块说明+效果图]
- P3387 【模板】缩点 Tarjan强连通分量/树上dp
- 测试你适合的发型软件叫什么,有没有测试发型的app 测试自己适合什么发型
- 攻防世界之misc1
- 老毛桃u盘重装win7教程|老桃毛U盘重装系统图文步骤
- Xshell的使用方法(初学者)
- PTGUI 720 制作全景图
- Linux x86 漏洞利用-Use-After-Free(UAF)-释放后可重用
热门文章
- 10大程序员实用网站,好网站不藏私
- select下拉框获取值
- python 文件后缀名 .py .pyc .pyw .pyo .pyd
- 教你使用Android SDK布局优化工具layoutopt
- SQLServer 密码验证登录18456错误解决方案
- 【vue】弹性布局和九宫格
- JSONObject.fromObject() 解析后出现的精度丢失问题
- linux作服务器的论文,基于Linux下的各种服务器技术及配置.rar
- 提高组比赛分析(1)
- 树言树语 输入法之争霸