内部排序 ——第3波——————【快速排序】

基本思想:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小。则可分别对这两部分记录继续进行排序,以达到整个序列有序。

一趟快速排序的做法:将枢纽记录暂存。附设两个指针low,high,初值分别是待排序列左右两端下标,设枢纽记录的关键字为pivotkey,先从high所指位置起向前搜索第一个小于pivotkey的记录,做记录high向记录low的单向移动。然后从low所指位置向后搜索第一个大于pivotkey的记录,做记录low向记录high的单向移动。直到low = high,说明关于枢纽pivotkey有序。然后将枢纽记录放到正确的位置即low。

 

时间复杂度:O(knlogn)。k为一个常数。就平均时间而言,快排是目前被认为是最好的一种内部排序。但是当记录有序或基本有序时,快排蜕化为起泡排序,时间复杂度是O(n*n)。

空间复杂度:O(n)。

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<string>
#include<iostream>
#include<queue>
#include<vector>
#include<set>
using namespace std;
typedef long long LL;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 300;
int a[maxn];
int Partition(int l,int r){ //一次划分,使得在pivotkey位置前面的值都比pivotkey小,后边都比它大
    int pivotkey = a[l];    //为了方便,选第一个为枢纽
    while(l < r){           //从表两端交替向中间扫描
        while(l < r && pivotkey <= a[r])
            r--;            
        a[l] = a[r];        //将小于pivotkey的记录移到左端
        while(l < r && pivotkey >= a[l])
            l++;
        a[r] = a[l];        //将大于pivotkey的记录移到右端
    }
    a[l] = pivotkey;        //将枢纽放到正确位置
    return l;
}
void Qsort(int l,int r){
    if(l < r){
        int id = Partition(l,r);    //得到枢纽位置。
        //同时l到r的记录关于pivotkey有序,即id左侧记录比pivotkey小,id右侧记录比pivotkey大
        Qsort(l,id-1);              //递归排序左部分子表
        Qsort(id+1,r);              //递归排序右部分子表
    }
}
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        for(int i = 1; i <= n; i++){
            scanf("%d",&a[i]);
        }
        Qsort(1,n);
    }
    return 0;
}

/*
7
49 38 65 97 76 13 27
*/

  

 

posted @ 2016-04-28 17:09  tcgoshawk  阅读(237)  评论(0编辑  收藏  举报