注意:我使用的是 python 2.7.3。我不确定其他版本的python是否会因除法而产生不同的结果,所以这里提个醒。
需要进行几处更改:
- 更改
mn != mx
为mn < mx
- 更改
pivot = mn + ((mx - mn) / 2)
声明以pivot = int(math.floor((mn + mx) / 2))
防止pivot = mn + int(math.floor((mx - mn) / 2))
在涉及分裂时出现任何意外。
mn
由 指示的搜索间隔mx
更改为由 给出的半开间隔,[mn, mx)
因为这是我在手动编码二进制搜索时更熟悉的内容。somx
应该设置为a
最初,并且mx
应该设置为pivot
而不是pivot - 1
在 where seq[a] <= seq[pivot]
(iow, if the if
test is False
) 的情况下。
因此,经过编辑的代码应如下所示:
import math
def insort(seq):
for a in xrange(1, len(seq)):
if seq[a] > seq[a - 1]:
continue
else:
mn, mx = 0, a
while mn < mx:
pivot = mn + int(math.floor(((mx - mn) / 2)))
if seq[a] > seq[pivot]:
mn = pivot + 1
else:
mx = pivot
seq.insert(mn, seq.pop(a))
对于原始代码,我会给你一个mx
卡住的例子-2
。
鉴于此列表:[10, 7, 8, 5, 13, 2, 6, 1, 50]
一切正常,直到索引 5 处的元素,其值为2
(通过添加一些print
语句自行验证)。由于seq[a] > seq[a-1]
is false (2
是迄今为止最小的元素),我们进入 if 语句的 else 分支。
在此刻:
seq = [5, 7, 8, 10, 13, 2, 6, 1, 50]
a = 5
mn = 0
mx = a - 1 = 4
从mn != mx
( 0 != 4
) 开始,我们进入 while 循环。pivot
设置为0 + ((4 - 0) / 2)
= 2
。接下来我们执行if seq[a] > seq[pivot]
。seq[a] = 2
, while seq[pivot]
= 8
and 2 > 8
is False
, 所以我们去 else 分支并执行mx = pivot - 1 = 2 - 1 = 1
在此刻:
seq = [5, 7, 8, 10, 13, 2, 6, 1, 50]
a = 5
mn = 0
mx = 1
我们再次在 while 循环中执行检查。mn != mx
( 0 != 1
),所以我们进入 while 循环的主体。我们设置pivot = 0 + ((1 - 0) / 2) = 0
(我使用python 2.7来执行这个除法,所以在repl处进行验证),然后执行检查seq[a] > seq[pivot]
(2 > 5
),即False
. 因此,我们设置mx = pivot - 1 = 0 - 1 = -1
。
在此刻:
seq = [5, 7, 8, 10, 13, 2, 6, 1, 50]
a = 5
mn = 0
mx = -1
mn != mx
现在,我们在 while 循环( )处执行检查0 != -1
,因此我们进入 while 循环的主体。pivot = 0 + ((-1 - 0) / 2) = -1
. 然后我们执行检查seq[a] > seq[pivot]
( seq[5] > seq[-1]
,将第 5 个元素与 的最后一个元素进行比较seq
,换句话说2 > 50
),即False
。所以mx = pivot - 1 = -1 - 1 = -2
。
现在我们已经到了最后一步:
seq = [5, 7, 8, 10, 13, 2, 6, 1, 50]
a = 5
mn = 0
mx = -2
在 while 循环检查,mn != mx
,所以我们继续pivot = 0 + ((-2 - 0) / 2) = -1
。请注意,这与上述步骤相同。然后seq[5] > seq[-1]
执行 ( 2 > 50
),即False
。所以mx = pivot - 1 = -1 - 1 = -2
。我们最终处于与上述相同的状态。这就是为什么你会看到一个无限循环。
最后,我只想说,二分搜索是一个非常棘手的算法,因为它很容易在边界索引上出错。我已经手动编写了很多次代码,但我仍然觉得它很棘手。您可能还想阅读此内容:http ://en.wikipedia.org/wiki/Binary_search_algorithm
希望有帮助!