zoukankan      html  css  js  c++  java
  • 排序算法之快速排序的python实现

    通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序。

    快速排序算法的工作原理如下:

    1. 从数列中挑出一个元素,称为"基准"(pivot)。

    2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。

    3. 在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

    4. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

     

    自我总结:快速排序的步骤就是首先将第一个数作为两边排序的数值,从第二个数开始对第一个数进行比较,如果大于第一个数将这个数放在第一个数的右边,小于放左边,依次进行比较并存放,最后将队列分成三个部分: 左边都比第一个数值小的数,第一个数值,右边都比第一各值大的数。这样就未完成了第一次排序的步骤。第二次是将前半部分的第一个值作为比较的”基数”,同第一次排序进行同样的比较和存放,直到原队列的第一个值之前的那个值。右边和左边做同样的比较,排序,直到之后一个值。这样依次进行递归,直到没有可以在分为左右的,这样就从小到大排序完成。

    最优时间复杂度:O(nlogn)

    n遍历每个数是O(n),访问每个数是O(logn),最终是O(nlogn)

    可以转换为求二叉树深度的思想

    最坏时间复杂度:O(n²)

    稳定性:不稳定

    优点:效率高,数据移动比较少,数据量越大,优势越明显

    缺点:不稳定

    下面为快速排序的代码实现:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    __author__ = "hsz"
    
    
    # 快排
    # first理解为第一个位置的索引,last是最后位置索引
    def quick_sort(alist, first, last):
        # 递归终止条件
        if first >= last:
            return
    
        # 设置第一个元素为中间值
        mid_value = alist[first]
        # low指向
        low = first
        # high
        high = last
        # 只要low小于high就一直走
        while low < high:
            # high大于中间值,则进入循环
            while low < high and alist[high] >= mid_value:
                # high往左走
                high -= 1
            # 出循环后,说明high小于中间值,low指向该值
            alist[low] = alist[high]
            # high走完了,让low走
            # low小于中间值,则进入循环
            while low < high and alist[low] < mid_value:
                # low向右走
                low += 1
            # 出循环后,说明low大于中间值,high指向该值
            alist[high] = alist[low]
        # 退出整个循环后,low和high相等
        # 将中间值放到中间位置
        alist[low] = mid_value
        # 递归
        # 先对左侧快排
        quick_sort(alist, first, low - 1)
        # 对右侧快排
        quick_sort(alist, low + 1, last)
    
    
    if __name__ == '__main__':
        li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
        print(li)
        quick_sort(li, 0, len(li) - 1)
        print(li)
  • 相关阅读:
    IBinder在进程之间传递一个对象的形式(一)
    Xaml在string(串)定义常量和处理空间
    c 有意思的数组初始化
    C 文件直接包含
    [面试技巧]16个经典面试问题回答思路
    centos6安装bt工具transmission
    clearcase 中一些概念和操作
    C/C++ Resources
    Linux I/O 重定向详解及应用实例
    c/c++ 直接使用动态库 dlopen
  • 原文地址:https://www.cnblogs.com/hszstudypy/p/11748930.html
Copyright © 2011-2022 走看看