麻省理工学院的算法简介将插入排序描述为:
我在Python中写道:
def sort(A):
for j in range(1, len(A)):
key = A[j];
i = j - 1;
# i > 0 should be i >= 0
while i > 0 and A[i] > key:
A[i + 1] = A[i]
i = i - 1;
A[i + 1] = key
return A
然而,行while i > 0
引入了一个错误 - 前两个键位于错误的位置。将此更改为while i >= 0
可解决此问题。
为什么这不包含在麻省理工学院的介绍书中?我读错了吗?
答案 0 :(得分:2)
本书中的算法假设从1到repaint()
的索引,包括在内,这就是它从索引2开始的原因.Python的数组索引从0到A.length
。您在len(A) - 1
中对此进行了更正,但您忽略了在循环测试中对其进行了更正。这样做可以解决问题。
答案 1 :(得分:0)
@pjs是完全正确的。我将补充说,一种有条不紊的方法将基于1的数组编写的算法转换为基于0的算法,没有一个错误的错误,就是按原样使用算法,除了在每个数组引用中减去1,然后使用代数简化。在这里你最终得到:
def sort(A):
for j in range(2, len(A) + 1): # +1 is because Python ranges exclude high limit
key = A[j - 1]
i = j - 1
while i > 0 and A[i - 1] > key:
A[i + 1 - 1] = A[i - 1]
i = i - 1
A[i + 1 - 1] = key
return A
当然,删除+ 1 - 1
可以很容易地简化,因为它增加了零!结果很好。
如果您希望使代码更漂亮,外部范围从1开始而不是2,请进行替换jj = j - 1
,其中(向两边添加1)表示j = jj + 1
:
def sort(A):
for jj in range(1, len(A)):
key = A[jj + 1 - 1]
i = jj + 1 - 1
while i > 0 and A[i - 1] > key:
A[i] = A[i - 1]
i = i - 1
A[i] = key
return A
再次移除+ 1 - 1
,我们有
def sort(A):
for jj in range(1, len(A)):
key = A[jj]
i = jj
while i > 0 and A[i - 1] > key:
A[i] = A[i - 1]
i = i - 1
A[i] = key
return A
这看起来很棒,我会在这里停下来。但是替换ii = i - 1
或i = ii + 1
可能会有另一种变体。
def sort(A):
for jj in range(1, len(A)):
key = A[jj]
ii + 1 = jj
while ii + 1 > 0 and A[ii + 1 - 1] > key:
A[ii + 1] = A[ii + 1 - 1]
ii + 1 = ii + 1 - 1
A[ii + 1] = key
return A
嗯......那些ii
的作业看起来很奇怪。但是我们可以再次用代数来解决所有问题。
def sort(A):
for jj in range(1, len(A)):
key = A[jj]
ii = jj - 1 # Subtracted 1 from both sides
while ii >= 0 and A[ii] > key: # x + 1 > 0 iff x >= 0
A[ii + 1] = A[ii]
ii = ii - 1 # Subtracted 1 from both sides and simplified
A[ii + 1] = key
return A
瞧,我们有你提出的代码。每次都有效。