快速排序有两种具体实现:双边循环法和单边循环法。
双边循环法
public void quicksort(int[] arr, int start, int end) {
int right = end, left = start;
if (right <= left) {
return;
}
int pivot = arr[left];
while (left != right) {
while (left < right && arr[right] >= pivot) {
right--;
}
while (left < right && arr[left] <= pivot) {
left++;
}
if (left < right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
}
arr[start] = arr[left];
arr[left] = pivot;
quicksort(arr, start, left-1);
quicksort(arr, left + 1, end);
}
双边循环法中while的顺序是不可以变的,必须是从右边开始(如果是实现升序的话)。
若是从左边开始,会出现left指针指向的元素大于基准元素。
如下图所示:
最后需要交换基准元素与left所指向的元素10,可以发现基准元素左边出现了比他大的数字。
故需要从右边开始扫描。
单边循环法
public void quicksort1(int[] arr,int start,int end) {
if (start >= end) {
return;
}
int mark = start;
int pivot = arr[start];
for (int i = start + 1; i <= end; i++) {
if (arr[i] < pivot) {
mark++;
int temp = arr[i];
arr[i] = arr[mark];
arr[mark] = temp;
}
}
arr[start] = arr[mark];
arr[mark] = pivot;
quicksort1(arr, start, mark-1);
quicksort1(arr,mark+1,end);
}
从左向右扫面,当有元素小于基准值时,就将mark加一,在将mark指向的元素和当前元素进行交换。
[start,mark]这个区间就是小于基准值的区域。