插入排序算法。逐步发生了什么?

时间:2018-09-13 05:46:01

标签: python algorithm insertion-sort

我是一名新的数据科学专业的学生,​​我试图了解插入排序算法内部到底发生了什么。

谁能一步一步告诉我发生了什么事?非常感谢。

下面是我用一些冗长的代码编写的代码,因此我希望可以了解正在发生的事情,但效果不佳。

A = [4, 1, 7, 52, 10, 12]
B = [4, 1, 7, 52, 10, 12]


def InsertionSort(A):

    for j in range(1, len(A)):

        print("***************** LOOP", j, "*********************\n")

        key = A[j]
        i = j - 1
        print("i:", i, " |  A[i]:", A[i], " |  key:", key, "\n")
        print("IS i:", i, ">= 0 and", A[i], ">", key, "?", "\n")

        while i >= 0 and A[i] > key:

            print("TRUE:", i, ">= 0 and", A[i], ">", key, "\n")

            A[i + 1] = A[i]  # left cell switches places with right cell
            i = i - 1

        A[i + 1] = key

    print("\n\n")
    print("=================== END =====================")


InsertionSort(A)
print("A (not-sorted): ", B)
print("A (sorted): ", A)

我不知道它是如何转换数字的。

3 个答案:

答案 0 :(得分:1)

Insertion sort的工作原理是查看数组中的每个元素,并将其移到数组的开头,直到它小于到目前为止所看到的所有内容。

为此,外部循环会考虑数组中的每个元素(跳过元素0,因为没有可与之比较的内容,并且您不想IndexError)。内部循环将元素从当前的i索引处开始向左滑动,将其与数组中的每个先前元素j-1进行比较,直到对迄今为止可见的数组部分进行排序为止。

您的调试输出过于依赖文本和数字,而不是数组的外观,而这只是查看算法运行情况所需要的。我还建议使用稍大的数组大小。

顺便说一句,我建议坚持使用Python camel_case naming convention

使用此repl并逐步完成输出,我想您会看到发生了什么事

a = [7, 3, 6, 9, 4, 5, 8, 0, 1, 2]

def insertion_sort(a):
    for i in range(1, len(a)):
        j = i
        print("moving %d:" % a[j])

        while j > 0 and a[j-1] > a[j]:
            a[j-1], a[j] = a[j], a[j-1]
            j -= 1
            print(a)
            print(" " + "   " * j + "^---")

        print()

print("original: \n" + str(a) + "\n")
insertion_sort(a)

输出:

original: 
[7, 3, 6, 9, 4, 5, 8, 0, 1, 2]

moving 3:
[3, 7, 6, 9, 4, 5, 8, 0, 1, 2]
 ^---       

moving 6:
[3, 6, 7, 9, 4, 5, 8, 0, 1, 2]
    ^---

moving 9:

moving 4:
[3, 6, 7, 4, 9, 5, 8, 0, 1, 2]
          ^---
[3, 6, 4, 7, 9, 5, 8, 0, 1, 2]
       ^---
[3, 4, 6, 7, 9, 5, 8, 0, 1, 2]
    ^---

moving 5:
[3, 4, 6, 7, 5, 9, 8, 0, 1, 2]
             ^---
[3, 4, 6, 5, 7, 9, 8, 0, 1, 2]
          ^---
[3, 4, 5, 6, 7, 9, 8, 0, 1, 2]
       ^---

moving 8:
[3, 4, 5, 6, 7, 8, 9, 0, 1, 2]
                ^---

moving 0:
[3, 4, 5, 6, 7, 8, 0, 9, 1, 2]
                   ^---
[3, 4, 5, 6, 7, 0, 8, 9, 1, 2]
                ^---
[3, 4, 5, 6, 0, 7, 8, 9, 1, 2]
             ^---
[3, 4, 5, 0, 6, 7, 8, 9, 1, 2]
          ^---
[3, 4, 0, 5, 6, 7, 8, 9, 1, 2]
       ^---
[3, 0, 4, 5, 6, 7, 8, 9, 1, 2]
    ^---
[0, 3, 4, 5, 6, 7, 8, 9, 1, 2]
 ^---

moving 1:
[0, 3, 4, 5, 6, 7, 8, 1, 9, 2]
                      ^---
[0, 3, 4, 5, 6, 7, 1, 8, 9, 2]
                   ^---
[0, 3, 4, 5, 6, 1, 7, 8, 9, 2]
                ^---
[0, 3, 4, 5, 1, 6, 7, 8, 9, 2]
             ^---
[0, 3, 4, 1, 5, 6, 7, 8, 9, 2]
          ^---
[0, 3, 1, 4, 5, 6, 7, 8, 9, 2]
       ^---
[0, 1, 3, 4, 5, 6, 7, 8, 9, 2]
    ^---

moving 2:
[0, 1, 3, 4, 5, 6, 7, 8, 2, 9]
                         ^---
[0, 1, 3, 4, 5, 6, 7, 2, 8, 9]
                      ^---
[0, 1, 3, 4, 5, 6, 2, 7, 8, 9]
                   ^---
[0, 1, 3, 4, 5, 2, 6, 7, 8, 9]
                ^---
[0, 1, 3, 4, 2, 5, 6, 7, 8, 9]
             ^---
[0, 1, 3, 2, 4, 5, 6, 7, 8, 9]
          ^---
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
       ^---

答案 1 :(得分:0)

与冒泡排序不同,插入排序不仅在概念上交换数字。

首先,它将当前索引j的值存储在变量key中。

然后,它从当前索引(i)的前一个索引i = j - 1开始,并向后向后(i = i - 1)遍历。对于每个索引,它都将值与keywhile i >= 0 and A[i] > key)进行比较。如果i上的值大于key,它将前移一个索引(A[i + 1] = A[i]),直到找到等于或小于key的值。找到这样的值后,key应该排在排序数组之后,因此它将key放在下一个索引i+1A[i + 1] = key)处。对所有元素都重复相同的过程,结果是排序数组。

这将帮助更多https://visualgo.net/bn/sorting?slide=8

答案 2 :(得分:0)

该函数正在排序给定的数组。首先,从第二个元素开始迭代数组的元素:

for j in range(1, len(A)):

然后将元素jkey)与元素j-1A[i])进行比较:

while i >= 0 and A[i] > key:

如果元素j-1大于元素j,则需要交换它们,因此需要进行交换:

A[i + 1] = A[i]

现在,它需要检查元素j-2是否也是如此,因此需要while循环。希望这会有所帮助。