泡泡排序作业

Jos*_*unt 128 python sorting algorithm bubble-sort

在课堂上我们正在做排序算法,虽然我在谈论它们和编写伪代码时理解它们很好,但我在编写实际代码时遇到了问题.

这是我在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)
Run Code Online (Sandbox Code Playgroud)

现在,这(据我所知)正确排序,但一旦完成它就会无限循环.

如何修复此代码以使函数正确完成并正确排序任何(合理)大小的列表?

PS我知道我不应该在函数中真正打印,我应该有一个返回,但我还没有这样做,因为我的代码还没有真正起作用.

Wes*_*ley 125

为了解释你的脚本现在无法正常工作的原因,我将把变量重命名unsortedsorted.

首先,您的列表尚未排序.当然,我们设定sortedFalse.

一旦我们开始while循环,我们就假设列表已经排序.这个想法是这样的:一旦我们发现两个元素的顺序不正确,我们就会sorted回过头来False.只有在错误的顺序中没有元素时sorted才会保留.True

sorted = False  # We haven't started sorting yet

while not sorted:
    sorted = True  # Assume the list is now sorted
    for element in range(0, length):
        if badList[element] > badList[element + 1]:
            sorted = False  # We found two elements in the wrong order
            hold = badList[element + 1]
            badList[element + 1] = badList[element]
            badList[element] = hold
    # We went through the whole list. At this point, if there were no elements
    # in the wrong order, sorted is still True. Otherwise, it's false, and the
    # while loop executes again.
Run Code Online (Sandbox Code Playgroud)

还有一些小问题可以帮助代码提高效率或可读性.

  • for循环中,您使用变量element.从技术上讲,element不是一个要素; 它是表示列表索引的数字.而且,它很长.在这些情况下,只需使用临时变量名称,例如i"index".

    for i in range(0, length):
    
    Run Code Online (Sandbox Code Playgroud)
  • range命令也可以只使用一个参数(命名stop).在这种情况下,您将获得从0到该参数的所有整数的列表.

    for i in range(length):
    
    Run Code Online (Sandbox Code Playgroud)
  • Python的风格指南建议变量用下划线小写字母来命名.对于像这样的小脚本来说,这是一个非常小的挑剔; 它让你习惯于Python代码最常用的东西.

    def bubble(bad_list):
    
    Run Code Online (Sandbox Code Playgroud)
  • 要交换两个变量的值,请将它们写为元组赋值.右侧被评估为元组(例如,(badList[i+1], badList[i])(3, 5)),然后被分配给左侧的两个变量((badList[i], badList[i+1])).

    bad_list[i], bad_list[i+1] = bad_list[i+1], bad_list[i]
    
    Run Code Online (Sandbox Code Playgroud)

把它们放在一起,你得到这个:

my_list = [12, 5, 13, 8, 9, 65]

def bubble(bad_list):
    length = len(bad_list) - 1
    sorted = False

    while not sorted:
        sorted = True
        for i in range(length):
            if bad_list[i] > bad_list[i+1]:
                sorted = False
                bad_list[i], bad_list[i+1] = bad_list[i+1], bad_list[i]

bubble(my_list)
print my_list
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,我也删除了你的打印声明.)

  • 这是冒泡排序的一个天真(但不是不正确)的实现.在`while`循环的每次迭代之后,最大的元素"冒泡"到列表的末尾.因此,在一次迭代之后,最后一个元素肯定在正确的位置(并且不会被连续的迭代移动).通过从长度中减去1,您只需对尚未排序的子列表(列表的"length-n"最前面的元素)进行排序来优化算法.我选择跳过此优化,因为它更像是优化而不是算法的重要部分. (20认同)
  • +1结构良好,明确的建议.很高兴看到你向读者介绍你做了什么以及为什么而不只是写一个快速修复. (9认同)
  • 就在最后一段代码中,bubble 不返回任何内容,因此最终结果是打印了 'None'。您可能想要返回列表,或者执行气泡(my_list)然后打印 my_list。 (2认同)
  • `把它们放在一起吧,你得到这个:`...好吧,你错过了这个:`range命令也可以只接受一个参数(名为stop). (2认同)

Nic*_*kis 10

冒泡排序的目的是在每一轮中移动较重的物品,同时将较轻的物品向上移动.在内部循环中,您比较元素,您不必在每个回合中迭代整个列表.将最重的已经放在最后.该交换变量是一个额外的检查,所以我们可以标记列表现在可以正确排序,并避免不必要的计算仍在继续.

def bubble(badList):
    length = len(badList)
    for i in range(0,length):
        swapped = False
        for element in range(0, length-i-1):
            if badList[element] > badList[element + 1]:
                hold = badList[element + 1]
                badList[element + 1] = badList[element]
                badList[element] = hold
                swapped = True
        if not swapped: break

    return badList
Run Code Online (Sandbox Code Playgroud)

你的版本1,更正:

def bubble(badList):
    length = len(badList) - 1
    unsorted = True
    while unsorted:
        unsorted = False
        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
                 unsorted = True
                 #print badList
             #else:
                 #unsorted = True

     return badList
Run Code Online (Sandbox Code Playgroud)


Mar*_*ote 8

当你使用负面含义的变量名时会发生这种情况,你需要反转它们的值.以下将更容易理解:

sorted = False
while not sorted:
    ...
Run Code Online (Sandbox Code Playgroud)

另一方面,算法的逻辑略微偏离.您需要检查for循环期间是否交换了两个元素.这是我写它的方式:

def bubble(values):
    length = len(values) - 1
    sorted = False
    while not sorted:
        sorted = True
        for element in range(0,length):
            if values[element] > values[element + 1]:
                 hold = values[element + 1]
                 values[element + 1] = values[element]
                 values[element] = hold
                 sorted = False
    return values
Run Code Online (Sandbox Code Playgroud)

  • 你们是对的,我过早回答了这个问题.对于那个很抱歉. (2认同)
  • @Martin - 我应该指出,我对投票比对答案更感到惊讶/震惊.声誉系统鼓励您立即获得第一个答案.破碎的部分是如何对错误的答案进行投票. (2认同)
  • 我怀疑大多数人投票时并没有真正理解这个问题(就像我回答问题的方式一样).OTOH,提出问题的人有权在事后选择"正确"的答案. (2认同)

Pau*_*ier 7

你使用Unsorted变量是错误的; 你想要一个变量,告诉你是否交换了两个元素; 如果你已经这样做了,你可以退出你的循环,否则你需要再次循环.要修复你在这里得到的东西,只需将"unsorted = false"放在你的if案例的正文中; 删除你的其他情况; 并在for循环之前放置"unsorted = true" .


mta*_*c85 6

def bubble_sort(l):
    for passes_left in range(len(l)-1, 0, -1):
        for index in range(passes_left):
            if l[index] < l[index + 1]:
               l[index], l[index + 1] = l[index + 1], l[index]
    return l
Run Code Online (Sandbox Code Playgroud)

  • 真的,也许,mtasic ......但任何被标记为家庭作业的东西都是最有教育意义的调整而不是重写(特别是当它被OP标记为家庭作业时). (6认同)
  • 你是绝对正确的,但以正确的方式做这件事更重要 (4认同)
  • 在我看来,添加好的信息很有帮助.如此好的答案..你应该尽可能使用旗帜打破. (2认同)