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