第一种,左右填坑法:这种方法很经典,首先抽取枢纽元素,然后设置两个指针分别从左右两端开始,将小于枢纽元素的填补到数组左端空缺位置,大于枢纽元素的填补到数组右端空缺位置,每次填补之后换成另一端开始遍历。
public static void quicksort(int[] array,int left,int right){
if(left>=right) return;
Random ra=new Random();
int i=ra.nextInt(right-left)+left,j=right;
int[] swap=swap(array[i],array[left]);
array[i]=swap[0];array[left]=swap[1];
int coreElem=array[left];
i=left;
while(i<j){
while(array[j]>coreElem&&i<j){j--;}
if(i<j) {
array[i]=array[j];
i++;
}
while(array[i]<coreElem&&i<j){i++;}
if(i<j){
array[j]=array[i];
j--;
}
}
array[i]=coreElem;
quicksort(array,left,i-1);
quicksort(array,i+1,right);
}
第二种,前后交换法:一种比较巧妙的实现方法,首先将枢纽元素放在最右端,设置两个指针从最左端出发,一先一后。一旦走在前面的firstPointer发现了比枢纽元素小的元素,就将该元素“抛到”secondPointer指向的下一个位置。最终形成left~secondPointer的元素都比枢纽小,而secondPointer~firstPointer的元素都大于或者等于枢纽元素。
public static int partition(int[] array,int left,int right){
int firstPointer=left,secondPointer=left-1;
Random ra=new Random();
int i=ra.nextInt(right-left)+left;
int[] swap=swap(array[i],array[right]);
array[i]=swap[0];array[right]=swap[1];
while(firstPointer<right){
if(array[firstPointer]<array[right]){
secondPointer++;
if(firstPointer!=secondPointer)
swap=swap(array[firstPointer],array[secondPointer]);
array[firstPointer]=swap[0];array[secondPointer]=swap[1];
}
firstPointer++;
}
array[++secondPointer]=array[right];
return secondPointer;
}
public static void quicksort(int[] array,int left,int right){
if(left>=right) return;
int partitionIndex=partition(array,left,right);
if(partitionIndex>left) quicksort(array,left,partitionIndex-1);
if(partitionIndex<right) quicksort(array,partitionIndex+1,right);
}
另附swap,java中比较简易的swap函数实现:
public static int[] swap(int a,int b){
return new int[]{b,a};
}