冒泡排序算法中的循环到底是如何工作的? (Python 3)

How exactly does the loop within a bubble sort algorithm work? (Python 3)

示例代码:

def bubble_sort(my_list):
    n = len(my_list)

    for i in range(n):
        for j in range(0, n - 1 - i):
            if my_list[j] > my_list[j + 1]:
                my_list[j], my_list[j + 1] = my_list[j + 1], my_list[j]


my_list = [94, 17, 5, 28, 7, 63, 44]
bubble_sort(my_list)
print(my_list)

在上面的代码中,我对嵌套循环的 for for __ in range() 部分感到困惑。这是做什么的,它是如何做到的?另外,my_list[j], my_list[j+1] = my_list[j+1], my_list[j] 如何重新排列列表值?抱歉,如果这听起来很愚蠢,但我想了解我正在编写的语法背后的逻辑,但我找不到可以很好地解释逻辑的地方,所以希望看到这个的人可以。感谢您的帮助!

好问题。我将尝试解决我在您的 post 中发现的两个问题。

问题 1:for __ in range() 是什么意思? range 函数只是生成一个数字列表。例如,假设 n = 5,则 range(5) 等于 range(n),在 return 中生成 [0, 1, 2, 3, 4]。此列表的长度为 5,0 为包含,5 为不包含。由于列表在 python 中是可迭代的,因此 for 循环会迭代列表。

例如:

for i in range(5): print(i, end=' ')

将打印 0 1 2 3 4

综上所述,嵌套循环的作用是什么?嗯,首先要注意的是,在这种情况下,范围从零 (0) 开始,这就是为什么你有 range(0, ...。真正令人困惑的是范围函数中的第二部分。为了理解为什么会这样,我们需要了解冒泡排序的行为方式。

以输入列表为例:

my_list = [94, 17, 5, 28, 7, 63, 44]

冒泡排序会这样排序:

[17, 5, 28, 7, 63, 44, 94]
[5, 17, 7, 28, 44, 63, 94]
[5, 7, 17, 28, 44, 63, 94]
[5, 7, 17, 28, 44, 63, 94]
[5, 7, 17, 28, 44, 63, 94]
[5, 7, 17, 28, 44, 63, 94]
[5, 7, 17, 28, 44, 63, 94]

现在,请注意关于冒泡排序组织列表的方式的一些非常有趣的事情。正在做的是取最大的数字并将其放在列表的末尾 (94),然后取第二大的数字并将其按顺序放在 94 旁边 (63),依此类推。实际上,我们的列表包含两侧,即有序端和无序端。由于我们已经订购了一些商品,因此没有理由重复这些商品。这就是为什么在表达式 n - 1 - i.

中有 - i

现在,您可能会问为什么要减去 -1。原因是交换,属于第二个问题。

问题 2:这个 (my_list[j], my_list[j + 1] = my_list[j + 1], my_list[j]) 重新排列我的项目?

上面的代码等同于用其他语言这样做:

int temp = item[i];
item[i] = item[i + 1];
item[i + 1] = temp;

为了更好地理解这一点,我们需要了解变量在编程中的工作原理。顾名思义,变量就是他们所说的,变量,意思是它们的值可能会改变。如果你给一个变量赋值,然后你给同一个变量赋另一个值,之前的值会被抹掉。

因为我们需要把item[i]的值放在item[i + 1]里面,所以这样做是不正确的

item[i] = item[i + 1]

因为那我们怎么分配

item[i + 1] = item[i]

因为我们删除了项目 [i] 中的先前值。在这种情况下,采取的方法是使用一个时间变量来保存 "containers" 之一的值,以便我们成功交换。唯一的问题是 python 通过使用语法糖并使程序员能够通过键入以下内容来交换值来完美地做到这一点:

(my_list[j], my_list[j + 1] = my_list[j + 1], my_list[j]) 

总结一下,对于第二个问题,我们加上-1,因为我们要交换最后一个和倒数第二个,而不会得到和IndexError