zoukankan      html  css  js  c++  java
  • 排序算法之快速排序

    快速排序的思想:

      分治法,将大问题分为若干个小的问题,解决小问题然后合成大问题的解

    典型的快速排序的一般过程:

      1、在数组中找到一个数,一般选作数组最后一个数作为中轴数X

      2、以中轴数X作为中心,使用一次划分partition,使得中轴数左边的数都比X小,右边的数都比X大,换句话说经历过一次划分后,中轴数X处在它本来应该在的位置上

      3、递归调用partition,最后使得整个数组有序

    一次划分partition过程:

     1 int partition(int data[],int start,int end){
     2     int i=start-1;   
     3     int j=start;
     4     int x=data[end];
     5     for(;j<end;j++){
     6         if(data[j]<x){
     7             ++i;
     8             exchange(data+i,data+j);
     9         }
    10     }
    11     exchange(data+i+1,data+end);
    12     return i+1;      //i标识的是数组中值小于X的最大下标,i+1即指一次划分后X所在的下标位置
    13 }

     递归调用的过程:

    1 void quicksort(int data[],int start,int end){
    2     if(start<end){
    3         int index=partition(data,start,end);
    4         quicksort(data,start,index-1);
    5         quicksort(data,index+1,end);
    6     }
    7 }

    注:函数的边界检查条件可以交付给上层调用函数来完成

     快速排序的时间复杂度分析:

      上述为了简便说明,总是选取待排序数组的最后一个元素作为中轴数,假设一种极端的情况,待排数组已经有序或者元素值全部相同,进行一次partition划分后,中轴数左右两边的元素个数分别是N-1,0,即每经过一次划分,就仅仅将一个数组元素放置在它应该在的位置上,剩余的N-1个数还需要继续排序,每次划分的时间复杂度为遍历一次待排数组所消耗的时间O(n)

      设整个排序的时间复杂度为T(n),则最坏的情况下,T(n)=T(n-1)+T(0)+O(n),可以递推得T(n)=O(n^2)

      算法的最佳时间复杂度,在最理想的情况下,每次划分总是将待排数组均衡划分,即一次划分完成后,中轴数左右两边的元素个数都是(N-1)/2,则其总的时间复杂度

      T(n)<=2*T(n/2)+O(n),T(n)=O(nlgn)

      算法的平均时间复杂度,T(n)=O(nlgn),(任何一种按常数比例进行的划分都会产生深度为O(lgn)的递归树,每一层的时间复杂度为进行一次划分的时间O(n),所以总的时间复杂度是O(nlgn)----算法导论),可以理解为,如果某一层的划分效果比较差,则该层下面的划分可能会比较好,好差划分随机的分布在递归树的各层,总的划分渐进于每层都是情况好的划分。

    快速排序的稳定性:

      由快排的三个过程可以知道,快排不是一种稳定的排序,例如[2,5,6,4(1),7,3,8,4(2)],经历一次划分后,数组变为[2,3,4(2),4(1),7,5,8,6],括号标识第1和第2个4.

    快速排序的改进:

      快速排序对于输入数组的随机性有要求,如果待排序的数组元素具有较大的随机性,则排序效果接近于基于比较的排序方法的下限O(nlgn),如果输入的数组基本有序,则不适用于快速排序。

      因此,对于待排序数组,可以给出快排的随机化版本,每次在划分之前,在数组中随机选择一个数T和数组中最后一个数X交换位置,交换过后调用上述partition函数,从而将随机选择的元素T作为中轴数,从而优化排序的性能。

    参考资料:《算法导论》

  • 相关阅读:
    那些年伴我一起成长的SAP装备
    1079. Total Sales of Supply Chain (25)
    1132. Cut Integer (20)
    1074. Reversing Linked List (25)
    1071. Speech Patterns (25)
    1070. Mooncake (25)
    1067. Sort with Swap(0,*) (25)
    1063. Set Similarity (25)
    1066. Root of AVL Tree (25)
    1059. Prime Factors (25)
  • 原文地址:https://www.cnblogs.com/sjinsa/p/4741114.html
Copyright © 2011-2022 走看看