泡泡排序作业

时间:2009-05-21 21:47:25

标签: python algorithm sorting 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)

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

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

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

28 个答案:

答案 0 :(得分:124)

要解释您的脚本现在无法正常工作的原因,我会将变量unsorted重命名为sorted

首先,您的列表尚未排序。当然,我们将sorted设置为False

一旦我们启动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.

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

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

    for i in range(0, length):
    
  • range命令也只能使用一个参数(名为stop)。在这种情况下,您将获得从0到该参数的所有整数的列表。

    for i in range(length):
    
  • Python Style Guide建议使用下划线以小写形式命名变量。对于像这样的小脚本来说,这是一个非常小的挑剔;更让你习惯于Python代码最常用的东西。

    def bubble(bad_list):
    
  • 要交换两个变量的值,请将它们写为元组赋值。右侧被评估为元组(例如,(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]
    

把它们放在一起,你就明白了:

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

(顺便说一句,我也删除了你的印刷语句。)

答案 1 :(得分:11)

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

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

您的第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

答案 2 :(得分:9)

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

sorted = False
while not sorted:
    ...

另一方面,算法的逻辑略微偏离。您需要检查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

答案 3 :(得分:8)

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

答案 4 :(得分:5)

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

答案 5 :(得分:4)

#A非常简单的功能,可以通过减少第二个数组的问题空间来优化(显然)。但是相同的O(n ^ 2)复杂度。

def bubble(arr):
    l = len(arr)        
    for a in range(l):
        for b in range(l-1):
            if (arr[a] < arr[b]):
            arr[a], arr[b] = arr[b], arr[a]
    return arr 

答案 6 :(得分:2)

你在那里遇到了一些错误。第一个是长度,第二个是未使用的(如McWafflestix所述)。如果要打印它,您可能还想返回列表:

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

def bubble(badList):
    length = len(badList) - 2
    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
                unsorted = True

    return badList

print bubble(mylist)

eta:你是对的,上面的马车就像地狱一样。我不喜欢通过更多的例子进行测试。

def bubble2(badList):
    swapped = True
    length = len(badList) - 2

    while swapped:
        swapped = False
        for i in range(0, length):
            if badList[i] > badList[i + 1]:

                # swap
                hold = badList[i + 1]
                badList[i + 1] = badList[i]
                badList[i] = hold

                swapped = True

    return badList

答案 7 :(得分:2)

我是一个新鲜的初学者,昨天开始阅读Python。 在你的例子的启发下,我创造了一些可能更多的80-ties风格的东西,但它仍然有点工作

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

i=0
while i < len(lista1)-1:
    if lista1[i] > lista1[i+1]:
        x = lista1[i]
        lista1[i] = lista1[i+1]
        lista1[i+1] = x
        i=0
        continue
    else:
        i+=1

print(lista1)

答案 8 :(得分:2)

原始算法的问题在于,如果列表中的数字更低,则不会将其带到正确的排序位置。程序需要每次都返回到开头,以确保数字一直排序。

我简化了代码,它现在适用于任何数字列表,无论列表如何,即使有重复的数字。这是代码

mylist = [9, 8, 5, 4, 12, 1, 7, 5, 2]
print mylist

def bubble(badList):
    length = len(badList) - 1
    element = 0
    while element < length:
        if badList[element] > badList[element + 1]:
            hold = badList[element + 1]
            badList[element + 1] = badList[element]
            badList[element] = hold
            element = 0
            print badList
        else:
            element = element + 1

print bubble(mylist)

答案 9 :(得分:2)

def bubble_sort(l):
    exchanged = True
    iteration = 0
    n = len(l)

    while(exchanged):
        iteration += 1
        exchanged = False

        # Move the largest element to the end of the list
        for i in range(n-1):
            if l[i] > l[i+1]:
                exchanged = True
                l[i], l[i+1] = l[i+1], l[i]
        n -= 1   # Largest element already towards the end

    print 'Iterations: %s' %(iteration)
    return l

答案 10 :(得分:2)

def bubbleSort(alist):
if len(alist) <= 1:
    return alist
for i in range(0,len(alist)):
   print "i is :%d",i
   for j in range(0,i):
      print "j is:%d",j
      print "alist[i] is :%d, alist[j] is :%d"%(alist[i],alist[j])
      if alist[i] > alist[j]:
         alist[i],alist[j] = alist[j],alist[i]
return alist

alist = [54,26,93,17,77,31,44,55,20,-23,-34,16,11,11,11]

print bubbleSort(alist)

答案 11 :(得分:2)

def bubble_sort(a):
    t = 0
    sorted = False # sorted = False because we have not began to sort
    while not sorted:
    sorted = True # Assume sorted = True first, it will switch only there is any change
        for key in range(1,len(a)):
            if a[key-1] > a[key]:
                sorted = False
                t = a[key-1]; a[key-1] = a[key]; a[key] = t;
    print a

答案 12 :(得分:2)

一个更简单的例子:

a = len(alist)-1
while a > 0:
    for b in range(0,a):
        #compare with the adjacent element
        if alist[b]>=alist[b+1]:
            #swap both elements
            alist[b], alist[b+1] = alist[b+1], alist[b]
    a-=1

这简单地将元素从0转换为a(基本上,该循环中的所有未排序元素)并将其与其相邻元素进行比较,并且如果它大于其相邻元素则进行交换。在回合结束时,最后一个元素被排序,并且该过程在没有它的情况下再次运行,直到所有元素都被排序。

不需要sort是否为真的条件。

请注意,此算法仅在交换时考虑数字的位置,因此重复的数字不会影响它。

PS。我知道这个问题发布已经很久了,但我只想分享这个想法。

答案 13 :(得分:1)

def bubble_sort(li):
    l = len(li)
    tmp = None
    sorted_l = sorted(li)
    while (li != sorted_l):
        for ele in range(0,l-1):
            if li[ele] > li[ele+1]:
                tmp = li[ele+1]
                li[ele+1] = li [ele]
                li[ele] = tmp
    return li

答案 14 :(得分:1)

arr = [5,4,3,1,6,8,10,9] # array not sorted

for i in range(len(arr)):
    for j in range(i, len(arr)):
        if(arr[i] > arr[j]):
            arr[i], arr[j] = arr[j], arr[i]

            print (arr)

答案 15 :(得分:1)

def bubblesort(array):
    for i in range(len(array)-1):
        for j in range(len(array)-1-i):
            if array[j] > array[j+1]:
                array[j], array[j+1] = array[j+1], array[j]
    return(array)

print(bubblesort([3,1,6,2,5,4]))

答案 16 :(得分:1)

def bubbleSort ( arr ):
    swapped = True 
    length = len ( arr )
    j = 0

    while swapped:
        swapped = False
        j += 1 
        for i in range ( length  - j ):
            if arr [ i ] > arr [ i + 1 ]:
                # swap
                tmp = arr [ i ]
                arr [ i ] = arr [ i + 1]
                arr [ i + 1 ] = tmp 

                swapped = True

if __name__ == '__main__':
    # test list
    a = [ 67, 45, 39, -1, -5, -44 ];

    print ( a )
    bubbleSort ( a )
    print ( a )

答案 17 :(得分:0)

尝试一下

a = int(input("Enter Limit"))


val = []

for z in range(0,a):
    b = int(input("Enter Number in List"))
    val.append(b)


for y in range(0,len(val)):
   for x in range(0,len(val)-1):
       if val[x]>val[x+1]:
           t = val[x]
           val[x] = val[x+1]
           val[x+1] = t

print(val)

答案 18 :(得分:0)

我想分享我的解决方案:

def bubble_sort(list_):
    for i in range(len(list_)):
        for j in range(i, len(list_)):
            if a[i] > a[j]:
                a[i], a[j] = a[j], a[i]
return list_

测试示例:

a = [8,1,2,4,1,3,5,1,5,6,1,8]
bubble_sort(a)

结果:

[1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 8, 8]

答案 19 :(得分:0)

def merge_bubble(arr):
    k = len(arr)
    while k>2:
        for i in range(0,k-1):
            for j in range(0,k-1):
                if arr[j] > arr[j+1]:
                    arr[j],arr[j+1] = arr[j+1],arr[j]

        return arr
        break
    else:
        if arr[0] > arr[1]:
            arr[0],arr[1] = arr[1],arr[0]
        return arr 

答案 20 :(得分:0)

愤怒和马丁科特提供的答案解决了无限循环的问题,但我的代码仍然无法正常工作(对于更大的列表,它不会正确排序。)。我最后放弃了unsorted变量,而是使用了一个计数器。

def bubble(badList):
    length = len(badList) - 1
    n = 0
    while n < len(badList):
        for element in range(0,length):
            if badList[element] > badList[element + 1]:
                hold = badList[element + 1]
                badList[element + 1] = badList[element]
                badList[element] = hold
                n = 0
            else:
                n += 1
    return badList

if __name__ == '__main__':
    mylist = [90, 10, 2, 76, 17, 66, 57, 23, 57, 99]
    print bubble(mylist)

如果有人可以提供关于如何在评论中改进我的代码的任何指示,那将非常感激。

答案 21 :(得分:0)

我考虑添加我的解决方案,因为这里的解决方案都有

  1. 更长的时间
  2. 更大的空间复杂度
  3. 或执行过多操作

然后应该是

所以,这是我的解决方案:


public function getUsersWithoutCurrent($i) {
    $qb = $this->createQueryBuilder('u');
    $qb->select('u.name')
        ->addSelect('u.email')
        ->addSelect('u.LastSeen')
        ->addSelect('u.slug')
        ->addSelect('u.roles')
        ->innerJoin('u.blogs', 'ub')
        ->setParameter('usr', $i)
        ->addSelect('COUNT(distinct(ub)) AS blogs')
        ->where($qb->expr()->notIn('u.id', ':usr'))
        ->groupBy('u.id')
    ;
    return $qb
        ->getQuery()
        ->getResult();
}

答案 22 :(得分:0)

如果有人对使用列表理解的较短实现感兴趣:

def bubble_sort(lst: list) -> None:
    [swap_items(lst, i, i+1) for left in range(len(lst)-1, 0, -1) for i in range(left) if lst[i] > lst[i+1]]


def swap_items(lst: list, pos1: int, pos2: int) -> None:
    lst[pos1], lst[pos2] = lst[pos2], lst[pos1]

答案 23 :(得分:0)

这是气泡排序的另一种变体,没有for循环。基本上,您正在考虑lastIndex中的array,然后慢慢地decrementing,直到它成为数组的第一个索引。

algorithm将继续像这样遍历整个数组,直到完成整个遍历而没有发生任何swaps

在性能方面,气泡基本上是Quadratic Time: O(n²)

class BubbleSort: 
  def __init__(self, arr):
    self.arr = arr;

  def bubbleSort(self):
    count = 0;
    lastIndex = len(self.arr) - 1;
    
    while(count < lastIndex):
      if(self.arr[count] > self.arr[count + 1]):
        self.swap(count)  
      count = count + 1;

      if(count == lastIndex):
        count = 0;
        lastIndex = lastIndex - 1;   

  def swap(self, count):
    temp = self.arr[count];
    self.arr[count] = self.arr[count + 1];
    self.arr[count + 1] = temp;
    
arr = [9, 1, 5, 3, 8, 2]
p1 = BubbleSort(arr)

print(p1.bubbleSort())

答案 24 :(得分:-1)

idk是否会在9年后对您有所帮助... 它是一个简单的气泡排序程序

GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();

List<Server> servers = gson.fromJson(json, 
  new TypeToken<List<Server>>(){}.getType()
);

答案 25 :(得分:-1)

def bubble_sort(l):
    for i in range(len(l) -1):
        for j in range(len(l)-i-1):
            if l[j] > l[j+1]:
                l[j],l[j+1] = l[j+1], l[j]
    return l

答案 26 :(得分:-1)

def bubble_sorted(arr:list):
    while True:
        for i in range(0,len(arr)-1):
            count = 0
            if arr[i] > arr[i+1]:
                count += 1
                arr[i], arr[i+1] = arr[i+1], arr[i]
        if count == 0:
            break
    return arr
arr = [30,20,80,40,50,10,60,70,90]
print(bubble_sorted(arr))
#[20, 30, 40, 50, 10, 60, 70, 80, 90]

答案 27 :(得分:-3)

class Cities(models.Model): city_main_image = models.FileField() city_name = models.CharField(max_length=200) city_info = models.CharField(max_length=1000) class CityImages(models.Model): city_id = models.ForeignKey(Cities) city_images = models.FileField()