内部排序 ——第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
*/
学学学 练练练 刷刷刷

浙公网安备 33010602011771号