为什么冒泡排序实现永远循环?
在课堂上,我们正在做排序算法,虽然我在谈论它们和编写伪代码时很好地理解它们,但我在为它们编写实际代码时遇到了问题。
这是我在 Python 中的尝试:
mylist = [12, 5, 13, 8, 9, 65]
def bubble(badList):
length = len(badList) - 1
unsorted = True
while unsorted:
for element in range(0,length):
unsorted = False
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
print badList
else:
unsorted = True
print bubble(mylist)
现在,(据我所知)排序正确,但一旦完成,它就会无限循环。
如何修复此代码以便函数正确完成并正确对任何(合理)大小的列表进行排序?
PS 我知道我不应该在函数中打印,并且应该有返回,但我只是还没有这样做,因为我的代码还没有真正工作。
In class we are doing sorting algorithms and, although I understand them fine when talking about them and writing pseudocode, I am having problems writing actual code for them.
This is my attempt in Python:
mylist = [12, 5, 13, 8, 9, 65]
def bubble(badList):
length = len(badList) - 1
unsorted = True
while unsorted:
for element in range(0,length):
unsorted = False
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
print badList
else:
unsorted = True
print bubble(mylist)
Now, this (as far as I can tell) sorts correctly, but once it finishes it just loops indefinitely.
How can this code be fixed so the function finishes properly and correctly sorts a list of any (reasonable) size?
P.S. I know I should not really have prints in a function and I should have a return, but I just have not done that yet as my code does not really work yet.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(28)
一个更简单的例子:
这只是将元素从 0 到 a(基本上是该轮中所有未排序的元素)并将其与其相邻元素进行比较,如果大于其相邻元素则进行交换。 在一轮结束时,对最后一个元素进行排序,并且该过程在没有它的情况下再次运行,直到所有元素都已排序。
不需要条件
sort
是否为真。请注意,该算法仅在交换时考虑数字的位置,因此重复的数字不会影响它。
A simpler example:
This simply takes the elements from 0 to a(basically, all the unsorted elements in that round) and compares it with its adjacent element, and making a swap if it is greater than its adjacent element. At the end the round, the last element is sorted, and the process runs again without it, until all elements have been sorted.
There is no need for a condition whether
sort
is true or not.Note that this algorithm takes into consideration the position of the numbers only when swapping, so repeated numbers will not affect it.
我考虑添加我的解决方案,因为这里的所有解决方案都需要
< strong>那么应该是
所以,这是我的解决方案:
I consider adding my solution because ever solution here is having
then is should be
So, here is my solution:
尝试这个
Try this
如果有人对使用列表理解的较短实现感兴趣:
If anyone is interested in a shorter implementation using a list comprehension:
这是不带
for
循环的冒泡排序的不同变体。 基本上,您正在考虑数组
的lastIndex
,并慢慢递减
直到它是数组的第一个索引。算法
将继续像这样在数组中移动,直到完成整个传递而没有发生任何交换
。就性能而言,冒泡排序基本上是
二次时间:O(n²)
。Here is a different variation of bubble sort without
for
loop. Basically you are considering thelastIndex
of thearray
and slowlydecrementing
it until it first index of the array.The
algorithm
will continue to move through the array like this until an entire pass is made without anyswaps
occurring.The bubble is sort is basically
Quadratic Time: O(n²)
when it comes to performance.the-fury 和 Martin Cote 提供的答案解决了无限循环的问题,但我的代码仍然无法正常工作(对于较大的列表,它无法正确排序。)。 我最终放弃了
unsorted
变量并使用了计数器。如果有人可以在评论中提供有关如何改进我的代码的任何指示,我将不胜感激。
Answers provided by the-fury and Martin Cote fixed the problem of the infinite loop, but my code would still not work correctly (for a larger list, it would not sort correctly.). I ended up ditching the
unsorted
variable and used a counter instead.If anyone could provide any pointers on how to improve my code in the comments, it would be much appreciated.
<代码>
def bubbleSort(a):
def 交换(x,y):
温度 = a[x]
a[x] = a[y]
a[y] = 温度
#外循环
对于范围内的 j(len(a)):
#切片到中心,内循环,python 风格
对于范围内的 i(j, len(a) - j):
#找到最小索引并交换
如果 a[i] < 一个[j]:
交换(j,i)
#找到最大索引并交换
如果a[i]> a[len(a) - j - 1]:
交换(len(a) - j - 1, i)
返回一个
def bubbleSort(a):
def swap(x, y):
temp = a[x]
a[x] = a[y]
a[y] = temp
#outer loop
for j in range(len(a)):
#slicing to the center, inner loop, python style
for i in range(j, len(a) - j):
#find the min index and swap
if a[i] < a[j]:
swap(j, i)
#find the max index and swap
if a[i] > a[len(a) - j - 1]:
swap(len(a) - j - 1, i)
return a
不知道这是否对 9 年后的你有帮助......
这是一个简单的冒泡排序程序
idk if this might help you after 9 years...
its a simple bubble sort program
冒泡排序的目标是在每轮中将较重的项目移动到底部,同时将较轻的项目向上移动。 在比较元素的内部循环中,您不必在每一轮中迭代整个列表。 最重的已经放在最后。 swapped 变量是一项额外的检查,因此我们可以标记列表现在已排序并避免继续不必要的计算。
您的版本 1,已更正:
The goal of bubble sort is to move the heavier items at the bottom in each round, while moving the lighter items up. In the inner loop, where you compare the elements, you don't have to iterate the whole list in each turn. The heaviest is already placed last. The swapped variable is an extra check so we can mark that the list is now sorted and avoid continuing with unnecessary calculations.
Your version 1, corrected:
为了解释为什么您的脚本现在不起作用,我将变量
unsorted
重命名为sorted
。首先,您的列表尚未排序。 当然,我们将
sorted
设置为False
。一旦我们启动
while
循环,我们就假设列表已经排序。 这个想法是这样的:一旦我们发现两个元素的顺序不正确,我们就将sorted
设置回False
。 仅当不存在顺序错误的元素时,sorted
才会保持True
。还有一些小问题可以帮助代码提高效率或可读性。
在
for
循环中,您使用变量element
。 从技术上讲,element
不是一个元素;而是一个元素。 它是一个代表列表索引的数字。 而且,它也相当长。 在这些情况下,只需使用临时变量名称,例如“index”的i
。range
命令也可以仅采用一个参数(名为stop
)。 在这种情况下,您将获得从 0 到该参数的所有整数的列表。Python 风格指南建议变量以小写字母并带下划线命名。 对于像这样的小脚本来说,这是一个非常小的挑剔; 更重要的是让您习惯 Python 代码最常见的相似之处。
要交换两个变量的值,请将它们写为元组赋值。 右侧被评估为一个元组(例如,
(badList[i+1], badList[i])
是(3, 5)
),然后被分配到左侧的两个变量 ((badList[i], badList[i+1])
)。把它们放在一起,你会得到这个:(
顺便说一句,我也删除了你的打印语句。)
To explain why your script isn't working right now, I'll rename the variable
unsorted
tosorted
.At first, your list isn't yet sorted. Of course, we set
sorted
toFalse
.As soon as we start the
while
loop, we assume that the list is already sorted. The idea is this: as soon as we find two elements that are not in the right order, we setsorted
back toFalse
.sorted
will remainTrue
only if there were no elements in the wrong order.There are also minor little issues that would help the code be more efficient or readable.
In the
for
loop, you use the variableelement
. Technically,element
is not an element; it's a number representing a list index. Also, it's quite long. In these cases, just use a temporary variable name, likei
for "index".The
range
command can also take just one argument (namedstop
). In that case, you get a list of all the integers from 0 to that argument.The Python Style Guide recommends that variables be named in lowercase with underscores. This is a very minor nitpick for a little script like this; it's more to get you accustomed to what Python code most often resembles.
To swap the values of two variables, write them as a tuple assignment. The right hand side gets evaluated as a tuple (say,
(badList[i+1], badList[i])
is(3, 5)
) and then gets assigned to the two variables on the left hand side ((badList[i], badList[i+1])
).Put it all together, and you get this:
(I removed your print statement too, by the way.)
这就是当您使用负含义的变量名时会发生的情况,您需要反转它们的值。 下面的内容会更容易理解:
另一方面,算法的逻辑有点偏离。 您需要检查 for 循环期间两个元素是否交换。 我会这样写:
This is what happens when you use variable name of negative meaning, you need to invert their values. The following would be easier to understand:
On the other hand, the logic of the algorithm is a little bit off. You need to check whether two elements swapped during the for loop. Here's how I would write it:
原始算法的问题是,如果列表中的数字较小,它不会将其带到正确的排序位置。 程序每次都需要返回开头,以确保数字完全排序。
我简化了代码,现在它适用于任何数字列表,无论列表如何,即使有重复的数字。 这是代码
The problem with the original algorithm is that if you had a lower number further in the list, it would not bring it to the correct sorted position. The program needs to go back the the beginning each time to ensure that the numbers sort all the way through.
I simplified the code and it will now work for any list of numbers regardless of the list and even if there are repeating numbers. Here's the code
我是一个刚入门的新手,昨天开始阅读有关Python的内容。
受你的例子的启发,我创造了一些可能更像 80 年代风格的东西,但无论如何它还是有用的
I am a fresh fresh beginner, started to read about Python yesterday.
Inspired by your example I created something maybe more in the 80-ties style, but nevertheless it kinda works
#一个非常简单的函数,可以通过减少第二个数组的问题空间来优化(显然)。 但复杂度相同 O(n^2)。
#A very simple function, can be optimized (obviously) by decreasing the problem space of the 2nd array. But same O(n^2) complexity.
你那里有几个错误。 第一个是长度,第二个是您对未排序的使用(如 McWafflestix 所述)。 如果您要打印该列表,您可能还想返回该列表:
eta:您是对的,上面的内容有很多错误。 我很遗憾没有通过更多示例进行测试。
You've got a couple of errors in there. The first is in length, and the second is in your use of unsorted (as stated by McWafflestix). You probably also want to return the list if you're going to print it:
eta: You're right, the above is buggy as hell. My bad for not testing through some more examples.
您对 Unsorted 变量的使用是错误的; 你想要一个变量来告诉你是否交换了两个元素; 如果你已经这样做了,你可以退出循环,否则,你需要再次循环。 要修复这里的问题,只需将“unsorted = false”放入 if 案例的正文中即可; 删除你的 else 案例; 并将“unsorted = true”放在
for
循环之前。Your use of the Unsorted variable is wrong; you want to have a variable that tells you if you have swapped two elements; if you have done that, you can exit your loop, otherwise, you need to loop again. To fix what you've got here, just put the "unsorted = false" in the body of your if case; remove your else case; and put "unsorted = true before your
for
loop.alist = [54,26,93,17,77,31,44,55,20,-23,-34,16,11,11,11]
打印 bubbleSort(alist)
alist = [54,26,93,17,77,31,44,55,20,-23,-34,16,11,11,11]
print bubbleSort(alist)