快速排序是交换排序中的一种重要方法,是一种效率较高的原址排序,算法思想在很多问题中都可以借鉴,比如说找到一个长度为N的序列中第m大的元素。
理想的排序时间复杂度为O(nlogn),最坏时间复杂度为O(n^2)
基本原理
原理1.对于一个无序序列,从中任选出一个元素P作为参照元素,将关键字小于P的元素全部放到P元素的左面,关键字大于P的元素全部放到P的右面,则此时P的位置为P在整个序列中的正确位置。
原理2.序列元素数量小于等于2时进行原理1的操作后将保证有序。
快速排序对一段无序序列按照原理1进行划分,则选中作为参照的元素将放到正确位置,并且在有序情况下本该位于参照元素前和后的元素分别位于此时无序情况下的前和后(也就是关键字小于参照元素的都排在参照元素前面,大于的都排参照元素后面),划分后出现两个新的子序列(可能为空),递归地对子序列按照原理1进行划分,直到序列为有序。
算法实现
参照元素可以任选,可以是随机位置也可以是固定的相对位置也就是第一个或者最后一个或者中间位置等,固定位置和随机位置具有相同的理论效率,但对于固定位置可以根据代码设计出故意为难我胖虎┑( ̄Д  ̄)┍的数据,使得出现最坏时间复杂度O(n^2),但随机位置就不存在了。
代码部分
这里是每次划分left到right之间的元素,选序列的最后一个元素作为参照元素,初始情况假设为全部元素大于选中参照元素,middle用来存放参照元素正确位置的下标,然后逐个检查,找到一个小于参照元素的就交换到middle前面,最后再将参照元素交换到正确位置,可以按照自己喜好来写。
唯一需要注意的是下面递归时写的middle-1,middle+1,可以自己理会。
- #include<iostream>
- #include<ctime>
- using namespace std;
- typedef int any;
- void quicksort(any ARRAY[],int left,int right){
- int middle=left;any temp; //middle为选出的参照元素的正确位置的下标
- for(int i=left;i<right;i++){
- //划分 将小于参照元素的元素middle位置前
- if(ARRAY[right]>ARRAY[i]){
- temp=ARRAY[middle];
- ARRAY[middle]=ARRAY[i];
- ARRAY[i]=temp;
- middle++;
- }
- }
- //最后将一开始选中的参照元素放到正确位置也就是ARRAY[middle]
- temp=ARRAY[right];
- ARRAY[right]=ARRAY[middle];
- ARRAY[middle]=temp;
- //对除开已经确定正确位置的ARRAY[middle]以外的元素继续划分
- if(middle>left)quicksort(ARRAY,left,middle-1);
- if(right>middle+1)quicksort(ARRAY,middle+1,right);
- }
- int main(){
- any p[10010]; //生成一组测试数据
- srand(time(time_t()));
- for(int i=0;i<10000;i++){
- p[i]=rand();
- }
- quicksort(p,0,9999);
- for(int i=0;i<10000;i++)cout<<p[i]<<endl;
- }