list 查找_趣味图解算法之二分查找

2ed508983ef8ea5978a996266d6953c6.gif

大多数程序员在看到"算法"两字的时候,是不是头大如斗。但如果想去大公司发展,在面试时又绕不过算法这座大山。市面上好多讲解算法的书籍(如算法导论)基本上都太学术、太复杂,对初学者很不友好。

因此小编准备换了思路,通过图解方法来分析复杂的算法实现,让初学算法朋友们不会再感到那么枯燥。

今天小编为读者老爷们带来了第一篇趣味图解算法之二分查找。

1、 简介

二分查找也叫折半查找,意思每次查找后,查找范围都折半。使用该查找方法有个前提条件就是要查找的元素必须是有序排列的。下面我们就来看看具体实现过程吧!

2、 算法分析

882a309b4f5f74a74a2d6586cc8aef94.png

如上图是一个顺序排列的数值元素列表,假定我们要查找图中值为19的元素,若使用普通的遍历方法,我们需要从第一个元素开始,将每一个元素与要查找的元素进行比较,直到找到对应元素值与要查找的元素值相等为止。使用这种方法会消耗非常长的时间(如果元素个数非常多),此时若使用二分查找算法那消耗的时间将大大降低。

现在我们使用二分查找算法来查找值为19的元素,如下图二分查找需要两个指针,一个指向元素列表的第一个元素叫做头指针,第二指向元素列表的最后一个元素的后一个Index(图中最后一个元素的Index为7,那么未指针就指向该元素的后一个Index,也就是图中的Index 8)叫尾指针。

要查找的范围就是头指针与尾指针之间的所有元素(注意:这边包含头指针所指向的元素但不包含尾指针指向的元素,其实尾指针并没有指向任何元素,只是指向了最后一个元素后一个Index)。

4f0074961185247076c18fa15cba4832.png

好了查找范围已经定下来了,接着我们开始查找吧。首先我们要寻找出查找范围的中间元素,可以通过头指针对应的Index值加上尾指针对应的Index值再除以2得出中间元素对应的Index。通过计算(0+8)/2=4可以得出中间元素的Index值为4,然后我们把该Index对应的元素值16与要查找的值19进行比较发现要查找的值大,不是要查找的值,所以我们将中间元素对应的Index值赋值给Head(因为示列元素列表是从小到大排列的)从而缩小查找范围,具体如下图所示。

08d7c1e39f200941cf53dfe2e92bd0b2.png

接着我们在新的范围中继续查找中间元素,计算(4+8)/2=6(这边有个注意点,如果不能整除则只取结果的整数部门如7/2只取3)得出中间元素Index为6,我们通过比较该Index指向元素值23是否与要查找的值19相等,发现中间元素的值比19大所以我们把中间元素Index值赋值给尾指针,具体如下图。

26f8c5e875b54c87c256cf8ae694147f.png

然后我们再在上图新的范围中查找中间元素,通过计算(4+6)/2=5得出中间元素对应的Index值为5,接着比较该中间元素值19与要查找的值19是否相等,发现两值正好相等至此我们的查找结束。

cfceff442d57c151ffecacf6f85a526e.png

3、 算法代码实现

上一个章节我们通过图解的方法已经了解了二分查找的实现原理,现在我们看看怎么用代码实现该算法吧,本节我们将通过python来演示,好了现在让我们来上代码:

1. #!/usr/bin/env/ python  2. # -*- coding:utf-8 -*-  3.   4. import time  5.   6.   7. def binary_search(search_list, search_value):  8.     """ 9.     :param search_list: 需要查找的数组列表 10.     :param search_value:  需要查找的值 11.     :return:  返回1表示已经查询到了, 返回-1表示没有查询到 12.     """  13.     head = 0 #设置head指针初始化的值  14.     tail = len(search_list) #要查询的列表元素长度就是尾指针的索引值  15.   16.     while tail - head > 1: #当尾指针与头指针的差等于1时退出巡检,此时查找的数就是head指针指向的数  17.         mid = (head + tail) // 2  #求出中间索引值  18.         # 如果中间索引值对应元素值小于要找的数值,则将这个中间索引值加1赋值给head指针  19.         # 这边加1是因为中间索引值对应的数小于查找的数值所以不应该把这个值包含在查找范围内  20.         if search_list[mid] 

代码执行结果,及耗时如下:

1. D:envpython3_envScriptspython3.exe E:/it_code/sf_content.py  2. 查找的结果:  1  3. 查找耗时:  0.000997781753540039  4.   5. Process finished with exit code 0  我们现在通过遍历的方法在相同的元素列表中查询相同的值看看耗费的时间,代码如下:1. def _search(search_list, search_value):  2.     for i in search_list:  3.         if i == search_value:  4.             return 1  5.     return -1  6.   7.   8. if __name__ == "__main__":  9.     search_list = [i for i in range(100000000)]  10.     start = time.time()  11.     print("查找的结果: ", _search(search_list, 9999999))  12.     end = time.time()  13.     print("查找耗时: ", end - start) 

执行的结果如下:

1. D:envpython3_envScriptspython3.exe E:/it_code/sf_content.py  2. 查找的结果:  1  3. 查找耗时:  0.27816343307495117  4.   5. Process finished with exit code 0  

怎么样是不是差距惊人,看来学好算法在处理实际问题时还是很有必须要的,今天我们的文章先到这里了,喜欢的朋友不要忘了关注、点赞与转发哦!

--喜欢的同学请点击@IT管理局关注哦--

本局精彩文章:

  • 玩转网络自动化之Netmiko模块
  • Wireshark数据包分析三板斧
  • 三步解决家里网速慢的问题
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值