我实现了以下代码,但我不知道为什么我认为运行速度更快的“快速”冒泡实际运行速度比预期慢。在第一个实现中,我认为我浪费了大量时间来检查每个数组是否已经排序,这需要花费O(n)时间。但是在第二个实现中,我正在检查数组是否按照我的交换进行排序,那么为什么第二个实现的运行速度比我想象的慢呢?
分配是否比完全遍历列表需要更多时间?
def check_sorted(A):
for i in xrange(1, len(A)):
if A[i] < A[i-1]:
return False
return True
def bubble_sort(A):
while not check_sorted(A):
for i in xrange(1, len(A)):
if A[i] < A[i-1]:
A[i], A[i-1] = A[i-1], A[i]
return A
def bubble_sort_fast(A):
swap = True
while swap:
swap = False
for i in xrange(1, len(A)):
if A[i] < A[i-1]:
A[i], A[i-1] = A[i-1], A[i]
swap = True
return A
A = list(reversed(range(5000)))
start_time = time.time()
A = bubble_sort(A)
print 'time_elapsed:', time.time() - start_time
A = list(reversed(range(5000)))
start_time = time.time()
A = bubble_sort_fast(A)
print 'time_elapsed:', time.time() - start_time
time_elapsed: 2.20229792595
time_elapsed (fast bubble sort): 2.38038301468
答案 0 :(得分:1)
“快”的人正在做更多的工作。添加计数器以查看他们执行其他人未执行操作的频率:
def check_sorted(A):
for i in xrange(1, len(A)):
global slow_checks; slow_checks += 1 # <== Added this
if A[i] < A[i-1]:
return False
return True
def bubble_sort_fast(A):
swap = True
while swap:
swap = False
for i in xrange(1, len(A)):
if A[i] < A[i-1]:
A[i], A[i-1] = A[i-1], A[i]
swap = True
global fast_marks; fast_marks += 1 # <== Added this
return A
你会发现slow_checks
最终为9998,而fast_marks
最终为12497500.这还有很多。确切地说,这是5000 * 4999/2,原始数据中的交换总数。
为什么slow_checks
这么小?好吧,因为从一个泡沫迭代到下一个泡泡迭代,你的列表就会像这样发展:
Start: [4999, 4998, 4997, 4996, 4995, ...
After bubbling 4999 up: [4998, 4997, 4996, 4995, 4994, ...
After bubbling 4998 up: [4997, 4996, 4995, 4994, 4993, ...
After bubbling 4997 up: [4996, 4995, 4994, 4993, 4992, ...
After bubbling 4996 up: [4995, 4994, 4993, 4992, 4991, ...
...
After bubbling 4 up: [3, 2, 1, 0, 4, 5, 6, 7, 8, 9, ...
After bubbling 3 up: [2, 1, 0, 3, 4, 5, 6, 7, 8, 9, ...
After bubbling 2 up: [1, 0, 2, 3, 4, 5, 6, 7, 8, 9, ...
After bubbling 1 up: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...
正如您所看到的,check_sorted
在查看前两个值后始终可以return False
!除了你最后一次问它,因为它会遍历整个列表并发现它已经排序。所以4999次它只进行一次检查,然后一次进行4999次检查,总计9998次检查。