赞
踩
说到二分查找,相信不少人小时候玩过猜数的游戏,在1~100之间随机挑选一个数,让别人来猜。如果别人猜错了,你要提示他猜的这个数随机数大还是比随机数小,别人继续猜,直到猜到为止。通常这个玩游戏的人都会从50开始猜,因为这样至少排除了一半不可能的数字。如果按照这个方法继续排除,在最大数为100的情况下,最多6次就能猜到这个随机数。这个猜数小游戏和二分查找的思想不谋而合。
目录
在一个有序数列里查找一个特定数列,顺序之前讲的顺序查找无疑是最没有效率的方法了。
二分查找的思想就是直接将数列中间的那个数与被查找数key相比较,如果这个数比被查找数key小,毫无疑问的就是被查找数一定在有序数列的后半部分中;否则被查找数一定在数列的前半部分。
我们还是以数列iList[0,1,2,3,4,5,6,7,8,9]为例,假设被查找数是9。
iLsit的长度为len(iList)=10,最中间的下标元素就是数列首元素的下标0和数列尾元素的下标9的和除以2,(0+9)/2=4。iList[mid]就是iList[4],第一次比较就是和iList[4]比较,如下图所示:
key比iList[4]大,所以key在iList[4]的后半部分。
后半部分的中间元素是iList[7],拿这个数和key值相比,若下图所示:
key比iList[7]要大,说明key在iList[7]的后半部分,但是此时后半部分中间元素下标是8,此时只剩下两个元素了,在使用二分查找就得不偿失了 。
不再使用二分法查找,直接比较这两个数和key是否相等,如果相等就返回该元素的下标,如果都不想等就返回未找到key的提示信息。如下图所示:
同样是查找9,顺序查找要查找10次才能找到(这是顺序查找最坏的情况),但是二分查找只需要查找3次(这是二分查找最坏情况),很明显二分查找要比顺序查找效率高。
randomLsit.py
- import random
-
- def randomList(n):
- '''返回一个长度为n的整数列表,数据范围[0,1000) '''
- iList = []
- for i in range(n):
- iList.append(random.randrange(1000))
- return iList
-
- if __name__ == "__main__":
- iList = randomList(10)
- print(iList)
quickSort.py
- from randomList import randomList
- import timeit
-
- iList = randomList(20)
-
- def quickSort(iList):
- if len(iList) <= 1:
- return iList
- left = []
- right = []
- for i in iList[1:]:
- if i <= iList[0]:
- left.append(i)
- else:
- right.append(i)
- return quickSort(left) + [iList[0]] + quickSort(right)
-
- if __name__ == "__main__":
- print(iList)
- print(quickSort(iList))
- print(timeit.timeit("quickSort(iList)", "from __main__ import quickSort,iList", number=100))

binarySearch.py
- from randomList import randomList
- from quickSort import quickSort
- import random
-
- iList = quickSort(randomList(20))
-
- def binarySearch(iList, key):
- print("iList = %s" %str(iList))
- print("Find The number : %d" %key)
- iLen = len(iList)
- left = 0
- right = iLen -1
-
- while right - left > 1:
- mid = (left + right) // 2
- if key < iList[mid]:
- right = mid
- elif key > iList[mid]:
- left = mid
- else:
- return mid
- if key == iList[left]:
- return left
- elif key == iList[right]:
- return right
- else:
- return -1
-
- if __name__ == "__main__":
- keys = [random.choice(iList), random.randrange(min(iList), max(iList))]
- for key in keys:
- res = binarySearch(iList, key)
- if res >= 0:
- print("%d is in the list, index is : %d\n" %(key, res))
- else:
- print("%d is not in the list\n" %key)

往期文章推荐:
排序篇:
查找篇:
如果喜欢这个系列的文章可以订阅我的算法设计与分析专栏,每天更新~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。