Python算法之『 冒泡、选择、快速排序算法的时间性能比较』

 

关于冒泡、选择、快速排序算法的Python实现代码,此处不赘述,完整代码请查看:

冒泡排序

选择排序

快速排序

 

问题1:就这三种排序算法而言,快排是否是最优方案?

问题2:冒泡和选择的时间复杂度相同,其时间性能表现是否真的相同(或者相差无几)?


 

一、在数组的无序程度较高的情况下

下面直接比较它们的时间性能,代码如下:

if __name__ == '__main__':
    import numpy
    import time

    t = time.time()
    for i in range(10000):
        array = list(numpy.random.randint(0, 100, 50))
    t0 = time.time() - t
    print('numpy生成50个0~100之间的数字,10000次所需时间:', t0, 's')

    t = time.time()
    for i in range(10000):
        array = list(numpy.random.randint(0, 100, 50))
        bubble_sort(array)
    print('冒泡排序:', time.time() - t - t0, 's')

    t = time.time()
    for i in range(10000):
        array = list(numpy.random.randint(0, 100, 50))
        select_sort(array)
    print('选择排序:', time.time() - t - t0, 's')

    t = time.time()
    for i in range(10000):
        array = list(numpy.random.randint(0, 100, 50))
        quick_sort(array)
    print('快速排序:', time.time() - t - t0, 's')

10000次的50是数字的排序时间消耗,多次试验结果如下:

numpy生成50个0~100之间的数字,10000次所需时间: 0.18699336051940918 s
冒泡排序: 1.6431183815002441 s
选择排序: 0.7640233039855957 s
快速排序: 0.4690079689025879 s

numpy生成50个0~100之间的数字,10000次所需时间: 0.1920773983001709 s
冒泡排序: 1.551903486251831 s
选择排序: 0.7149889469146729 s
快速排序: 0.5479793548583984 s

numpy生成50个0~100之间的数字,10000次所需时间: 0.20493817329406738 s
冒泡排序: 1.5134046077728271 s
选择排序: 0.6773779392242432 s
快速排序: 0.4561192989349365 s

numpy生成50个0~100之间的数字,10000次所需时间: 0.1710827350616455 s
冒泡排序: 1.5479202270507812 s
选择排序: 0.7355144023895264 s
快速排序: 0.49486231803894043 s

结论:

1、虽然选择排序和冒泡排序的时间复杂度都是O(n^2),但是显然选择排序要优于冒泡排序,时间消耗大约是其1/2,大约节省50%的时间。

2、快速排序在这三个方法中表现最好,时间消耗大约是冒泡排序的1/3。


二、在数组为正序(从小到大排列)的情况下

if __name__ == '__main__':
    import time

    print([i for i in range(50)])
    
    t = time.time()
    for i in range(10000):
        array = [i for i in range(50)]
    t0 = time.time() - t
    print('生成10000次数据所需时间:', t0, 's')

    t = time.time()
    for i in range(10000):
        array = [i for i in range(50)]
        bubble_sort(array)
    print('冒泡排序:', time.time() - t - t0, 's')

    t = time.time()
    for i in range(10000):
        array = [i for i in range(50)]
        select_sort(array)
    print('选择排序:', time.time() - t - t0, 's')

    t = time.time()
    for i in range(10000):
        array = [i for i in range(50)]
        quick_sort(array)
    print('快速排序:', time.time() - t - t0, 's')

测试结果:

生成10000次数据所需时间: 0.012993097305297852 s
冒泡排序: 0.8310296535491943 s
选择排序: 0.6019954681396484 s
快速排序: 1.3461222648620605 s

生成10000次数据所需时间: 0.01307988166809082 s
冒泡排序: 0.8245120048522949 s
选择排序: 0.6059088706970215 s
快速排序: 1.3093125820159912 s

生成10000次数据所需时间: 0.012005090713500977 s
冒泡排序: 0.9179930686950684 s
选择排序: 0.6651043891906738 s
快速排序: 1.4826264381408691 s

总结:在正序(已排好序)的情况下,快排算法的优势就发挥不出来了,变成了最差者;选择排序依然优于冒泡排序,大约节省25%的时间。


三、在数组为反序(从大到小排列)的情况下

if __name__ == '__main__':
    import time

    print([i for i in range(50, 0, -1)])
    
    t = time.time()
    for i in range(10000):
        array = [i for i in range(50, 0, -1)]
    t0 = time.time() - t
    print('生成10000次数据所需时间:', t0, 's')

    t = time.time()
    for i in range(10000):
        array = [i for i in range(50, 0, -1)]
        bubble_sort(array)
    print('冒泡排序:', time.time() - t - t0, 's')

    t = time.time()
    for i in range(10000):
        array = [i for i in range(50, 0, -1)]
        select_sort(array)
    print('选择排序:', time.time() - t - t0, 's')

    t = time.time()
    for i in range(10000):
        array = [i for i in range(50, 0, -1)]
        quick_sort(array)
    print('快速排序:', time.time() - t - t0, 's')

测试结果:

生成10000次数据所需时间: 0.014925479888916016 s
冒泡排序: 2.075543165206909 s
选择排序: 0.7910571098327637 s
快速排序: 1.2525396347045898 s

生成10000次数据所需时间: 0.012000799179077148 s
冒泡排序: 2.0227086544036865 s
选择排序: 0.7382717132568359 s
快速排序: 1.2780859470367432 s

生成10000次数据所需时间: 0.012999534606933594 s
冒泡排序: 2.0591678619384766 s
选择排序: 0.7919540405273438 s
快速排序: 1.3123962879180908 s

总结:在反序(顺序正好是由大到小排列的)的情况下,快排依然不理想。冒泡排序也变得更差了,选择比冒泡节省大约60%的时间。选择排序是三者的最优算法。


 

“敲黑板”

1、虽然选择排序和冒泡排序的时间复杂度都是O(n^2),但时间复杂度和实际的时间消耗并不严格对等,在上述三种情况下,选择排序都优于冒泡排序。所以不要陷入“时间复杂度相同,其时间消耗就应该很相近”的误区中

2、快排的优势只能在无序程度较高的情况下才能发挥出来,对于已经有序的数列(无论是正序还是反序),其表现都不会很优秀。

3、选择排序是三者中,选择排序是时间性能最稳定的一个,基本在0.6~0.8s;冒泡排序是三种中时间性能最不稳定的一个,基本在0.8~2.0s。

 

 

Mr.bai

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
排序算法是计算机科学中用于对一组数据进行有序排列的基本操作,常见的排序算法冒泡排序选择排序、快速排序和归并排序。在 Python 中,这些算法可以通过内置函数 `sorted()` 或者自定义函数来实现。以下是简单介绍: 1. **冒泡排序 (Bubble Sort)**: 冒泡排序是一种简单的比较排序算法,它的基本思想是重复地遍历待排序的序列,每次比较相邻的两个元素,如果它们的顺序错误就把它们交换过来。Python 示例: ```python def bubble_sort(lst): n = len(lst) for i in range(n): for j in range(0, n-i-1): if lst[j] > lst[j+1]: lst[j], lst[j+1] = lst[j+1], lst[j] return lst ``` 2. **选择排序 (Selection Sort)**: 选择排序每次从未排序的部分找到最小(或最大)的元素,并将其放到已排序部分的末尾。Python 实现: ```python def selection_sort(lst): for i in range(len(lst)): min_idx = i for j in range(i+1, len(lst)): if lst[j] < lst[min_idx]: min_idx = j lst[i], lst[min_idx] = lst[min_idx], lst[i] return lst ``` 3. **快速排序 (Quick Sort)**: 快速排序是一种分治算法,通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,然后分别对这两部分记录继续进行排序,直到整个序列有序。Python 示例(使用 Hoare 变换): ```python def quick_sort(arr, low, high): if low < high: pivot_index = partition(arr, low, high) quick_sort(arr, low, pivot_index - 1) quick_sort(arr, pivot_index + 1, high) def partition(arr, low, high): pivot = arr[high] i = low - 1 for j in range(low, high): if arr[j] <= pivot: i += 1 arr[i], arr[j] = arr[j], arr[i] arr[i+1], arr[high] = arr[high], arr[i+1] return i + 1 ``` 4. **归并排序 (Merge Sort)**: 归并排序也是一种分治算法,它将待排序的序列分为两半,分别排序,然后合并。Python 示例: ```python def merge_sort(arr): if len(arr) <= 1: return arr mid = len(arr) // 2 left_half = merge_sort(arr[:mid]) right_half = merge_sort(arr[mid:]) return merge(left_half, right_half) def merge(left, right): merged = [] left_idx, right_idx = 0, 0 while left_idx < len(left) and right_idx < len(right): if left[left_idx] <= right[right_idx]: merged.append(left[left_idx]) left_idx += 1 else: merged.append(right[right_idx]) right_idx += 1 merged.extend(left[left_idx:]) merged.extend(right[right_idx:]) return merged ``` 如果你想深入了解这些排序算法的工作原理、性能以及适用场景,可以继续提问哦。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值