1.哨兵位置爲最終位置
2.partition就是切分過程
3.選擇一個哨兵,將一組數劃分爲全比它小、全比它大的左右兩部分,再分別對這兩部分繼續如此左右劃分,直到元素個數爲1.整個劃分結束時,數組已排好序。
4.至於partition過程,參見上圖。
5.圖一的劃分方式,退出循環後i所指爲第一個大於等於vot的元素,j所指爲最後一個小於等於vot的元素。因此最後使a[j]與a[lb]交換即可讓哨兵歸至原位。
僞碼:
void quickSort(int a[],int p,int r){
if(p<r){
int q=partition(a,p,r);
quickSort(a,p,q-1);
quickSort(a,q+1,r);
}
}
代碼:
import java.util.Scanner;
public class 快排遞歸 {
static void swap(int a[],int i,int j) {
int tmp = a[i];
a[i]=a[j];
a[j]=tmp;
}
static int partition(int a[],int lb,int ub) {
//以下爲圖一劃分方式
int i=lb,j=ub+1;
int vot=a[i];
while(true) {
while(i<ub&&a[++i]<vot);
while(a[--j]>vot);
if(i<j) swap(a,i,j);
else break;
}
a[lb]=a[j];
a[j]=vot;
return j;
//以下爲圖二劃分方式
/*int i=lb,j=ub;
int vot=a[i];
while(true) {//一旦j==i就終止循環。因爲左遊標左側、右遊標右側代表已處理妥當的元素。而左右遊標之所指,代表要互相比較的兩個元素。相遇時,遊標左右已妥,而遊標本身進行對比不會改變什麼。因此結束。
while(j>i&&a[j]>=vot) j--;
if(j>i) {//加這個條件是篩掉,如,基準元素左側全是比它小的。下同。
a[i++]=a[j];
}
while(j>i&&a[i]<=vot) i++;
if(j>i) {
a[j--]=a[i];
}
if(!(j>i)) break;
}
a[i]=vot;
return i;*/
}
static void quickSort(int a[],int lb,int ub) {
int q=-1;
if(ub>lb) {
q=partition(a, lb, ub);
quickSort(a, lb, q-1);
quickSort(a, q+1, ub);
}
}
public static void main(String args[]) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int a[]=new int[n];
for(int i=0;i<n;i++) {
a[i]=sc.nextInt();
}
quickSort(a, 0, n-1);
for(int i=0;i<n;i++) {
System.out.println(a[i]);
}
}
}