简体   繁体   English

插入排序 python 算法:为什么要从 i 中减去 1?

[英]Insertion sort python algorithm: Why do we subtract 1 from i?

Here is the code:这是代码:

list_a = [3,2,5,7,4,1]

def insertion_sort(list_a):
  indexing_length = range(1,len(list_a))

  for i in indexing_length:
    value_to_sort = list_a[i]

    while list_a[i-1] > value_to_sort and i>0:
      list_a[i], list_a[i-1] = list_a[i-1], list_a[i]  
      i = i - 1
  
  return list_a

I understand the logic to the rest of the algorithm but I can't seem to grasp the logic for doing i = i - 1. Can someone explain please?我理解算法 rest 的逻辑,但我似乎无法理解执行 i = i - 1 的逻辑。有人可以解释一下吗?

Hi and welcome to SO,您好,欢迎来到 SO,

range(a, b) in python is equivalent to [a, b[ in mathematics with a and b two floating numbers and a < b python 中的range(a, b)等同于数学中的[a, b[具有ab两个浮点数且a < b

And range(b) is equivalent to [0, b[ in mathematics.range(b)相当于数学上的[0, b[

in insertion sort, you select each value and go back ward to place in the corresponding place where it is smaller than right part and bigger than left part.在插入排序中,您将每个值 select 和 go 向后放置在它小于右侧部分且大于左侧部分的相应位置。

probably this gif from wikimedia describes it well.可能来自维基媒体的这个 gif 很好地描述了它。 if embedded gif not wokring look at the link: https://upload.wikimedia.org/wikipedia/commons/9/9c/Insertion-sort-example.gif如果嵌入的 gif 不起作用,请查看链接: https://upload.wikimedia.org/wikipedia/commons/9/9c/Insertion-sort-example.gif

在此处输入图像描述

for this reason you need the i = i -1 to go backwrd and place in the correct place.出于这个原因,您需要 i = i -1 到 go backwrd 并将其放在正确的位置。

Consider an example: arr = [12, 11, 13, 5, 6]考虑一个例子: arr = [12, 11, 13, 5, 6]

The array is virtually split into a sorted and an unsorted part.该数组实际上分为已排序和未排序的部分。 Values from the unsorted part are picked and placed at the correct position in the sorted part.未排序部分的值被挑选并放置在已排序部分的正确 position 中。

First Pass:第一关:

Starting with first two elements从前两个元素开始

   12          11          13          5       6   

Here, 12 is greater than 11 hence they are not in the ascending order and 12 is not at its correct position. Thus, swap 11 and 12. So, for now 11 is stored in a sorted sub-array.在这里,12 大于 11,因此它们不在升序中,并且 12 不在其正确的 position。因此,交换 11 和 12。因此,现在 11 存储在已排序的子数组中。

Second Pass:第二关:

Now, move to the next two elements and compare them现在,移动到下两个元素并比较它们

   11          12          13          5       6   

Here, 13 is greater than 12, thus both elements seems to be in ascending order, hence, no swapping will occur.在这里,13 大于 12,因此两个元素似乎都按升序排列,因此不会发生交换。 12 also stored in a sorted sub-array along with 11. 12 也与 11 一起存储在已排序的子数组中。

Third Pass:第三关:

Now, Moving forward to the next two elements which are 13 and 5现在,前进到下两个元素,即 13 和 5

   11          12          13          5       6   

Both 5 and 13 are not present at their correct place so swap them 5 和 13 都没有出现在正确的位置,所以交换它们

   11          12          5       13          6   

After swapping, elements 12 and 5 are not sorted, thus swap again交换后,元素 12 和 5 没有排序,因此再次交换

   11          5       12          13          6   

Here, again 11 and 5 are not sorted, hence swap again在这里,11 和 5 再次未排序,因此再次交换

   5       11          12          13          6   

here, it is at its correct position在这里,它是正确的 position

Then we repeat same process in each pass.然后我们在每次传递中重复相同的过程。

You can see from example when one pair of elements isn't in the correct order we keep swapping them from the index of current element backwards till they are in the correct order.您可以从示例中看到,当一对元素的顺序不正确时,我们会不断从当前元素的索引向后交换它们,直到它们的顺序正确为止。 that's why we set i = i - 1 in the algorithm code.这就是我们在算法代码中设置i = i - 1的原因。

Without,i=i-1 the adjacent elements are checked once. Without,i=i-1 ,则检查一次相邻元素。 so, at the end [2,3,5,7,4,1] would become [2,3,5,4,1,7] .所以,最后[2,3,5,7,4,1]会变成[2,3,5,4,1,7] For this (without i = i-1) to work you need to implement double for loop like below and may replace while loop with if condition or leave as it is.为此(没有 i = i-1)工作,您需要像下面那样实现双 for 循环,并且可以用if condition替换while loop或保持原样。

在此处输入图像描述

def insertion_sort(list_a):
  indexing_length = range(1,len(list_a))
  #this is double for-loop
  for _ in indexing_length:
      for i in indexing_length:
        # print(i)
        value_to_sort = list_a[i]
        if list_a[i-1] > value_to_sort and i>0:
          list_a[i], list_a[i-1] = list_a[i-1], list_a[i]  
        print(list_a)
  
  return list_a

Actually above method is easy to understand and taught everywhere where we check every two adjacent elements twice, But to reduce the number of comparisons checks we can use while loop with i = i-1.实际上上面的方法很容易理解并且在我们检查每两个相邻元素两次的地方都有教,但是为了减少比较检查的次数我们可以使用 i = i-1 的 while 循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM