排序问题 (下) 【快速排序】【小结】

    快速排序  :    

    原理:

     快速排序法采用 “ 分而治之 ” 的方法,把一个串行分为两个串行。

    排序过程:

  1. 从数列中挑出一个元素,称为 “基准”(pivot);
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

    注意:

  1. 选取基准:
            选取基准的方法:取 头、中、尾 的中位数。
            这里,我们选用Median3函数来实现此方法。在下方的代码中将会具体介绍。
  2. 子集划分:
            当进行上面的排序过程的 2 操作时,如果有元素正好等于 基准 ,停下来做交换比较好。

    例如:对 3、13、10、4、9进行排序。
在这里插入图片描述

    代码如下:

#include <iostream>

using namespace std;

int N=8;
int A[8];
int Pivot;

int Median3(int A[],int left,int right)                       /*选取基准, 取  头、中、尾  的中位数。*/
{
   int center=(left+right)/2;

   if( A[left] > A[center] )  swap( A[left] , A[center]);
   if( A[left] > A[right] )  swap( A[left] , A[right]);
   if( A[center] > A[right] )  swap( A[center] , A[right]);
   /*使得   A[left]<=A[center]<=A[right]*/

   swap( A[center] , A[right]);        /*将基准放到右边*/
   /*因为在上面的三个if判断里,已经作出了三者的排序,
   所以,只需要考虑A[left+1]至A[right-1]之间的数*/

   return A[right];
}
void Quick_Sort (int A[],int left,int right)
{
   Pivot=Median3(A , left ,right);

   int i=left,j=right-1;

   for(; ;)
   {
      while (A[i] < Pivot)  i++;

      while (A[j] > Pivot)  j--;

      if(i<j)   swap(A[i],A[j]);
      else      break;

   }

   swap(A[i],A[right]);

   if(left<i-1)  Quick_Sort(A,left,i-1);         /*递归地把小于基准的元素进行排序*/

   if(right>i+1)  Quick_Sort(A,i+1,right);        /*递归地把大于基准的元素进行排序*/



}
int main()
{
   for(int i=0;i<N;i++)  cin >> A[i];

   Quick_Sort(A,0,N-1);
   
   for(int i=0;i<N;i++) cout << A[i]<<endl;
   
   return 0;

}

    ADDITION:

  • 快速排序使用的是递归,对于小规模的数据(例如N不到100)可能还不如插入排序快。
  • 因此,当递归的数据规模充分小,则停止使用递归,直接使用简单排序。
  • 时间复杂度:O(n logn)      O(n^2);
  • 稳定性:不稳定。

    各种排序比较  :    

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值