排序之快速排序

喜欢将自己的学习之路记录下来!

快速排序是排序算法中比较重要的一种,所以想记录下来。快排,是冒泡排序的一种改进。

其思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。我的理解就是将一个序列通过一个特定的值分为两部分,是左边的比右边的小(升序),递归的完成这个阶段,最后整个序列为有序。

步骤如下:

1. 设置两个变量i、j,排序开始的时候:i=0,j=N-1;

2.以第一个数组元素作为关键数据,赋值给key,即key=A[0];

3.从前往后找大于key值,从后往前找小于key的值,再将两个交换,直到i>=j,即划分完成。

4.递归的对左右两个序列进行上述过程。

划分代码如下:

<pre name="code" class="cpp">int partition(T *data,int begin,int end){
    T temp = data[begin];
    while(begin<end){
        while(end>begin&&data[end]>temp)    //从右边往寻找比中值小的
            --end;
        data[begin]=data[end];            //将小值放到左边
        while(end>begin&&data[begin]<=temp)   //从左边往右边找比中间大的
            ++begin;
        data[end]=data[begin];            //将大值放到右边
        
    }
    data[begin]=temp;           //放置标记值
    return begin;
}

 

排序代码:

<pre name="code" class="cpp">void quicksort(T *data,int begin,int end){
    if (begin<end){
        int mod = partition(data,begin,end);
        quicksort(data,begin,mod-1);
        quicksort(data,mod+1,end);
    }
}


 
 
快排性能分析: 

最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(n*n)

在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:O(nlgn)

尽管快速排序的最坏时间为O(n2),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。它的平均时间复杂度为O(nlgn)。

总体来说,快速排序是一种高效排序算法。

所有代码:

/* 
* @Author: ice
* @Date:   2015-09-09 23:12:20
* @Last Modified by:   anchen
* @Last Modified time: 2015-09-10 22:27:30
*/

#include <iostream>
#include <algorithm>
#include <ctime>
constexpr int SIZE =16; 
using namespace std;
template <typename T>

int partition(T *data,int begin,int end){
    T temp = data[begin];
    while(begin<end){
        while(end>begin&&data[end]>temp)    //从右边往寻找比中值小的
            --end;
        data[begin]=data[end];            //将小值放到左边
        while(end>begin&&data[begin]<=temp)   //从左边往右边找比中间大的
            ++begin;
        data[end]=data[begin];            //将大值放到右边
        
    }
    data[begin]=temp;           //放置标记值
    return begin;
}

template <typename T>

void quicksort(T *data,int begin,int end){
    if (begin<end){
        int mod = partition(data,begin,end);
        quicksort(data,begin,mod-1);
        quicksort(data,mod+1,end);
    }
}
int main(){
    srand(time(NULL));
    int a[SIZE];
    for (int i = 0; i < SIZE; ++i){
        a[i]=rand()%100;
        cout<<a[i]<<" ";
    }
    clock_t t1,t2;
    t1=clock();
    quicksort(a,0,SIZE-1);
    for (int i = 0; i < SIZE; ++i){
        cout<<a[i]<<" ";
    }
    t2=clock();
    cout<<endl;
    cout<<t2-t1<<endl;
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值