在python中对列表进行冒泡排序最有效吗?
我想看看这是否是python中对冒泡列表进行排序的最有效方法,或者是否有人告诉我使用两个循环的更好方法,与下面的方法相比,这样做的好处是什么在python中对列表进行冒泡排序最有效吗?,python,algorithm,performance,bubble-sort,Python,Algorithm,Performance,Bubble Sort,我想看看这是否是python中对冒泡列表进行排序的最有效方法,或者是否有人告诉我使用两个循环的更好方法,与下面的方法相比,这样做的好处是什么 def sort_bubble(blist): n = 0 while n < len(blist) - 1: if blist[n] > blist[n + 1]: n1 = blist[n] n2 = blist[n + 1] blist
def sort_bubble(blist):
n = 0
while n < len(blist) - 1:
if blist[n] > blist[n + 1]:
n1 = blist[n]
n2 = blist[n + 1]
blist[n] = n2
blist[n + 1] = n1
n = 0
else:
n = n + 1
print blist
def排序气泡(blist):
n=0
当nblist[n+1]:
n1=blist[n]
n2=blist[n+1]
blist[n]=n2
blist[n+1]=n1
n=0
其他:
n=n+1
印刷布利斯特
如果我被迫使用冒泡排序,我会这样做,您可能应该始终使用python中的默认sort()函数,它非常快
def BubbleSort(A):
end = len(A)-1
swapped = True
while swapped:
swapped = False
for i in range(0, end):
if A[i] > A[i+1]:
A[i], A[i+1] = A[i+1], A[i]
swapped = True
end -= 1
它基本上是常规的bubblesort,但不是每次只遍历最后一个交换的值时遍历整个列表,根据定义,它遍历的是任何已经存在的值
此外,您不需要在python中使用临时值进行交换,python的方法是:
a , b = b , a
从技术上讲,您的算法是一种冒泡排序,因为它所做的交换正是它应该做的。然而,这是一种非常低效的冒泡排序,因为它所做的比必要的要多得多 你怎么知道?通过插入代码来计算比较和交换的数量非常容易。同时,给出了一个简单的冒泡排序的实现,以及一个带有跳过排序尾部优化的实现,使用一种伪代码语言,很容易移植到Python和类似的工具。我将在底部显示代码 对于一个完美的冒泡排序,给定一个长度为100的随机列表,您应该期望少于10000次比较(100*100),少于2500次交换。而维基百科的实现正是这样做的。“跳过排序的尾部”版本应该有一半以上的比较,而且确实如此 然而,你的产品的对比度是它应有的10倍。您的代码效率低下的原因是它一次又一次地从头开始,而不是尽可能地从交换代码的地方开始。这会导致额外的系数
O(sqrt(N))
同时,对于几乎任何输入,几乎任何排序算法都优于冒泡排序,因此即使是有效的冒泡排序也不是有效排序
我对您的代码做了一个小改动:用更惯用的单行交换替换四行交换。否则,除了添加
cmpcount
和swapcount
变量,并返回结果而不是打印结果之外,什么都不会更改
def bogo_bubble(blist):
cmpcount, swapcount = 0, 0
n = 0
while n < len(blist) - 1:
cmpcount += 1
if blist[n] > blist[n + 1]:
swapcount += 1
blist[n], blist[n+1] = blist[n+1], blist[n]
n = 0
else:
n = n + 1
return blist, cmpcount, swapcount
这是一个简单的跳过排序尾部优化版本,但不是更复杂的版本(紧随其后)
典型输出:
bogo_bubble: 100619 cmp, 2250 swap
wp1_bubble : 8811 cmp, 2250 swap
wp2_bubble : 4895 cmp, 2250 swap
你可以自己测试一下。其他事情保持不变,只需计算迭代次数,您就会知道什么更快。以下是我写的:
def sort_bubble(blist):
ops=0
n = 0
while n < len(blist) - 1:
if blist[n] > blist[n + 1]:
n1 = blist[n]
n2 = blist[n + 1]
blist[n] = n2
blist[n + 1] = n1
n = 0
else:
n = n + 1
ops+=1
print ops
print blist
def bubbleSort(list):
ops=0
for i in range(len(list)):
for j in range(i):
if list[i] < list[j]:
list[i], list[j] = list[j], list[i]
ops+=1
print ops
return list
sort_bubble([ 6,5, 3 ,1, 8, 7, 2, 4])
print bubbleSort([ 6,5, 3 ,1, 8, 7, 2, 4])
def排序气泡(blist):
ops=0
n=0
当nblist[n+1]:
n1=blist[n]
n2=blist[n+1]
blist[n]=n2
blist[n+1]=n1
n=0
其他:
n=n+1
ops+=1
打印操作
印刷布利斯特
def bubbleSort(列表):
ops=0
对于范围内的i(len(列表)):
对于范围(i)中的j:
如果列表[i]<列表[j]:
列表[i],列表[j]=列表[j],列表[i]
ops+=1
打印操作
返回列表
排序气泡([6,5,3,1,8,7,2,4])
打印气泡排序([6,5,3,1,8,7,2,4])
气泡列表与普通列表有什么不同吗?我建议使用内置的list.sort()
方法。您是否在问(a)这是否是实现冒泡排序的最(算法上)有效的方法,(b)冒泡排序是否是排序的有效方法,或者(c)完全不同的方法?还有,仅仅要求我们将您的代码与您模糊地描述为“使用两个循环”的代码进行比较几乎是不可能的。尝试以两种方式编写代码,使实现尽可能相似(因此更改是显而易见的)。然后你可以自己测试它(使用,或通过计算步数,或…)。如果结果证明它比您的代码更高效,并且您无法找出原因,那么您将面临一个巨大的堆栈溢出问题;只需执行blist[n],blist[n+1]=blist[n+1],blist[n]
。TLDR:不,即使对于气泡,OP也是无效的sort@gnibbler:那就在第一段。“然而,这是一种非常低效的泡沫排序,因为它所做的比较比必要的要多得多。”我怀疑任何读不到第二行的人都会读评论……这只计算比较的数量,而不是互换的数量。由于他的算法碰巧第一个错误,第二个正确,结果是正确的。你是对的。出于某种原因,我倾向于在算法设计中忽略赋值操作。在大计划中,它们是固定成本的,对吧。嗯,是的,但是比较也是固定成本的。问题是,有多少人?我相信OP的预期设计,如果做得好的话,会有4倍于交换的比较,交换很容易就需要4倍于比较的时间,所以你不能因为恒定的4倍而忽略它们。事实证明,他有4*sqrt(N)x比较,这就是错误所在,超常量因子意味着你可以忽略交换,但如果你事先不知道…
bogo_bubble: 100619 cmp, 2250 swap
wp1_bubble : 8811 cmp, 2250 swap
wp2_bubble : 4895 cmp, 2250 swap
def sort_bubble(blist):
ops=0
n = 0
while n < len(blist) - 1:
if blist[n] > blist[n + 1]:
n1 = blist[n]
n2 = blist[n + 1]
blist[n] = n2
blist[n + 1] = n1
n = 0
else:
n = n + 1
ops+=1
print ops
print blist
def bubbleSort(list):
ops=0
for i in range(len(list)):
for j in range(i):
if list[i] < list[j]:
list[i], list[j] = list[j], list[i]
ops+=1
print ops
return list
sort_bubble([ 6,5, 3 ,1, 8, 7, 2, 4])
print bubbleSort([ 6,5, 3 ,1, 8, 7, 2, 4])