本文是我对二分查找的学习和认识,很多人都在说二分查找是基本算法中的基础,考察一个人写算法的基本功,个人很是赞同,当初裸写(学习后不借助任何书或网络)
二分算法很是恼火,发现并解决了各种问题,现在记录心得如下:(代码写得丑,不要在意这些细节 0.0)
什么是二分查找 ?
大家都清楚所谓二分,便是一分为二,将一个问题划分成两个小一点的子问题,我们所找的目标一定在我们划分的两个子问题中的一个,我们就可以在很大程度上节省时间(毕竟查找范围不断地缩小)我问过度娘,萌娘百科,不,度娘百科轻轻地告诉我二分查找优点在于比较次数少、查找速度快、平均性能好,然,缺点甚是明了,只可查有序表且插入删除困难。写代码无非周全,写算法无非细节,考察算法无非也是考察各种细节。话不多说,代码参上:
#coding=utf-8
# l:左边界
# r:右边界
print '快速查找'
def quicksort(item,l,r,i,isproc=False):
right = r
left = l
mid = (right+left)/2
while left < right:
if isproc == True:
print mid,left,right
if i == item[left]:
return left
if i == item[right]:
return right
if i == item[mid]:
return mid
if i < item[mid]:
#print 'i(%s) < %s|item[%s]'%(i,item[mid],mid)
right = mid - 1
if i > item[mid]:
#print 'i(%s) > %s|item[%s]'%(i,item[mid],mid)
left = mid + 1
mid = (right+left)/2
else:
print '成功完成快速查找'
ap = [4,9,14,8,274,-882192,913,-492,-3]
print '%s 中查找%s,其位置:%s'%(ap,14,quicksort(ap,0,len(ap)-1,14))
print '%s 中查找%s,其位置:%s'%(ap,8,quicksort(ap,0,len(ap)-1,8))
apc = [4,9,14,19,274,4821,91342]
print '%s 中查找%s,其位置:%s'%(apc,91342,quicksort(apc,0,len(apc)-1,91342))
unsi = [92,23,52,-45,175,99,3,-24,-7,3,0]
print '%s 中查找%s,其位置:%s'%(unsi,99,quicksort(unsi,0,len(unsi)-1,99,False))
你问我 为毛叫quicksort,我想说不要在意这些细节
代码并不多,可是要独自写出来可不易,参数的检验是交由调用者完成的,我们无条件信任调用者。
我依旧如C语言一样,提供Left,Right参数自定义list(在C语言中的数组基本等价Python的list对象)的查找边界,len并没有写进函数里
如果你担心 mid溢出 ,那么你可以灵活变换一下使用 mid = left +(right - left)/2 可以解决少见的溢出问题
对于while循环条件,right = = left ,真的没几个人会这么蛋疼的拿[4,4]的区间或者单个元素来让你找不同的,即便是循环造成的也无大碍我们有大if语句在
情况无非,我们的目标 i 在 mid上,i 或在 mid右,i 亦或在 mid左,还是i 在 left 上,i 也是可在 right上
在坐标mid、right、left上的,问君犹豫什么,赶快告诉妈妈(输出啊,adc,快上)
不在那我们去邻居家找,在 mid右边,left = mid + 1,同理,对于在mid左边的藏匿的同学,right = mid - 1
把查找范围尺调整,边界right或left使原来的查找范围缩小一半,left ,mid,right相对位置不变就可以继续循环找,left和right相遇了就够了,不能再找了。
循环最后更新了边界坐标,怎能亏待mid呢,也要mid = (left+right)/2 刷新刷新
总得来说还看得过去,此代码可以较为巧妙地运用在非有序表上,至今我没发现什么问题
看来不认真写博客,以后工作都找不到了