插入排序 - 麻烦阅读麻省理工学院介绍阿尔戈斯

时间:2016-10-12 22:49:46

标签: algorithm insertion-sort array-algorithms

麻省理工学院的算法简介将插入排序描述为:

MIT Algo image

我在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可解决此问题。

为什么这不包含在麻省理工学院的介绍书中?我读错了吗?

2 个答案:

答案 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 - 1i = 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

瞧,我们有你提出的代码。每次都有效。