• 快速排序


    快速排序

    快速排序是对冒泡排序的一种改进。基本思想是分治法:在待排序表 L[1.....n]中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分 L[1...k-1]和 L[k+1...n] ,使得L[1...k-1]的所有元素小于pivot,L[k+1...n]中所有元素大于pivot,则pivot放在了其最终位置L(k)上,这个过程称为一趟快速排序。而后分别递归的对两个子表重复上述过程,直至每部分内只有一个元素或空为止,即所有元素放在了其最终位置。

    快速排序思路:

    a. 取一个元素p(第一个元素),使元素p归位;
    b. 列表被p分成两部分,左边都比p小,右边都比p大;
    c. 递归完成排序。

    假设划分算法已知,记为partation(),递归的调用快排,具体结构如下:

    def quick_sort(data, left, right):
        if left < right:
            mid = partition(data, left, right)
            quick_sort(data, left, mid - 1)
            quick_sort(data, mid + 1, right)
    

     可以看出快排关键在于划分操作,同时快排性能也主要取决于划分操作好坏。

    对于划分算法,假设每次总是以当前表中第一个元素作为枢纽值(基准)对表进行划分,则必须将表中枢纽值大的元素向右移,比枢纽值小的向左移动,使得一趟partition()操作后,表中的元素被枢纽值一分为二。

    def partition(data, left, right):
        tmp = data[left]
        while left < right:
            while left < right and data[right] >= tmp:
                right -= 1
            data[left] = data[right]
            while left < right and data[left] <= tmp:
                left += 1
            data[right] = data[left]
        data[left] = tmp
        return left
    

    快排性能分析:

    空间效率:

    由于快排是递归的,需要借助一个递归工作栈来保存每一层递归调用的必要信息,其容量应于递归调用的最大深度一致。最好情况下为[log(n+1)];最坏情况下,O(n)。所以空间复杂度:平均为O(logn),最坏情况O(n)。

    时间效率:与划分是否对称有关,快排最坏情况发生在两个划分区域分别含n-1个元素和0个元素时,这种最大程度的不对称性发生在每一层递归上,就得到最坏情况下的时间复杂度O(n^2)。如所有逆序排列的元素,对其进行快排,时间复杂度O(n^2)。

    在理想状态下partition()可以做到最平衡的划分,此时时间复杂度为O(nlogn)。

    快速排序是内部排序平均性能最优的算法。

    快排在划分算法时,若右端区间存在两个关键字相同,且均小于基准值记录,则在交换到左区间后,相对位置发生变化,故快排是一个不稳定排序方法。

     

    Dylan
  • 相关阅读:
    Java的几种常用设计模式
    面向切面编程AOP
    面向过程编程、面向对象编程
    Java基础之集合与泛型
    Spring mvc中自定义拦截器
    Hibernate框架hibernate.cfg.xml配置文件,配置自动生成表结构策略。
    Notepad++打开xml文件显示crlf的问题
    java框架
    潜龙博客地址
    联通
  • 原文地址:https://www.cnblogs.com/dylan123/p/10700427.html
Copyright © 2020-2023  润新知