QuickSort 操作
基本思想
(1)选取待排序数组中的某个元素K(例如第1个元素)作为基准元素(也称为主元、轴点,Pivot),按照其关键词的大小,对数组重新排列,使整个数组划分为左右两个子数组:
左侧子数组中元素的值都小于或等于K;
右侧子数组中元素的值都大于K;
基准元素K排在两个子数组中间。
(2)分别对两个子数组重复上述方法,直至所有元素都排在正确位置上。
<=K | K | >K |
特点:一趟划分把一个记录放在最终的位置上(K)。
简要描述
void QuickSort(int R[], int n) {
if (R的长度大于1) {
将R划分为两个子数组LeftR 和 RightR;
QucikSort(LeftR);
QuickSort(RightR);
}
}
Partition操作
基本思想
把比K大的元素移到数组右边,把比K小的元素移到数组左边。
引入两个指针L和G相向而行:
指针L从左向右扫描数组找第一个>k的元素,指针G从右向左找第一个<=K的元素,交换R[L]和R[G]。重复如此,不断把<=K的元素换到数组左边,大于K的元素换到数组右边,直至指针L和G相遇。
int Partition(int R[], int m, int n) {
int K = R[m], L = m + 1, G = n; //K为基准,选取第一个元素
while (L <= G) {
while (L <= n && R[L] <= K) L++; //从左到右找第一个>K的元素
while (R[G] > K) G--; //从右到左找第一个<=K的元素
if (L < G) {
swap(R[L], R[G]); //若找到,交换
L++;
G--;
}
}
swap(R[m], R[G]); //把基准换到左右子数组中间
return G;
}
快速排序算法
void QuickSort(int R[], int m, int n) {
if (m < n) {
int k = Partition(R, m, n);
QuickSort(R, m, k - 1);
QuickSort(R, k, n);
}
}
初始调用
QuickSort(R,1,n);
实际使用简洁版
void QuickSort(int R[],int m,int n){
if(m>=n) return; //递归出口
int K=R[m+n>>1]; //选取中间值作为基准;>>1为右移1位,相当于/2
int l=m-1,r=n+1; //l为左指针,r为右指针
while(l<r){
do l++; while(R[l]<K); //找第一个>=K的元素
do r--; while(R[r]>K); //找第一个<=K的元素
if(l<r) swap(R[l],R[r]);
}
QuickSort(R,m,l); //处理左子数组
QuickSort(R,l+1,n); //处理右子数组
}