快速排序是对冒泡排序的一种改进。其基本思想是基于分治法的:在待排序表L[1...n]中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分L[1...k-1]和L[k+1...n],使得L[1...k-1]中所有元素小于pivot,L[k+1...n]中所有元素大于或等于pivot,则pivot放在最终位置L(k)上,这个过程称一趟快速排序。而后分别递归地对两个子表重复上述过程,直至每部分内只有一个元素或空为止,即所有元素放在了其最终的位置上。
首先假设划分算法已知,记为partition(),返回的是上述中的k,注意到L(k)已经在最终的位置,所以可以先对表进行划分,而后对两个表调用相同的排序操作。因此可以递归地的调用快速排序算法进行排序,具体的程序结构如下:
1 public static void quickSort(int[] array, int low, int high) {
2 if (low < high) {//递归跳出的条件
3 int pivotpos = partition(array, low, high);
4 //partition()即是划分操作,将表划分为两个子表
5 quickSort(array, low, pivotpos - 1);
6 quickSort(array, pivotpos + 1, high);//依次对两个子表进行递归
7 }
8 }
从上面的代码也不难看出快速排序算法的关键在于划分操作,同时快速排序算法的性能也主要取决于划分操作的好坏。本人参考严蔚敏老师所著教材上的划分操作思想,假设每次总是以当前表中第一个元素作为枢纽(基准)对表进行划分,则必须将表中比枢纽值大的元素向右移动,比枢纽值小的元素向左移动,使得一趟partition()操作之后,表中的元素被枢纽值一分为二。
//严版教材中的划分算法(一趟排序过程)
public static int partition(int[] array, int low, int high) {
int pivot = array[low];//将表中第一个元素设为枢纽值,对表进行划分
while (low < high) {//循环跳出条件
while (low < high && array[high] >= pivot) {
high--;//将比枢纽值小的元素移动到右端
}
array[low] = array[high];
while (low < high && array[low] <= pivot) {
low++;//将比枢纽值大的元素移动到左端
}
array[high] = array[low];
}
array[low] = pivot;//将枢纽元素放回最终位置
return low;//返回存放枢纽的最终位置
}
运行下试试:
int[] arr = new int[]{43, 25, 71, -42, 45, -69, 11, 31, 29, -4, 0, -17, 21};
将该数组进行快排
/*
数组的快速排序
*/
public class quickSort {
public static void main(String[] args) {
int[] arr = new int[]{43, 25, 71, -42, 45, -69, 11, 31, 29, -4, 0, -17, 21};
System.out.println("排序前:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
quickSort(arr, 0, arr.length - 1);
System.out.println();
System.out.println("排序后:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
public static void quickSort(int[] array, int low, int high) {
if (low < high) {
int pivotpos = partition(array, low, high);
quickSort(array, low, pivotpos - 1);
quickSort(array, pivotpos + 1, high);
}
}
//严版教材中的划分算法(一趟排序过程)
public static int partition(int[] array, int low, int high) {
int pivot = array[low];//将表中第一个元素设为枢纽值,对表进行划分
while (low < high) {//循环跳出条件
while (low < high && array[high] >= pivot) {
high--;//将比枢纽值小的元素移动到右端
}
array[low] = array[high];
while (low < high && array[low] <= pivot) {
low++;//将比枢纽值大的元素移动到左端
}
array[high] = array[low];
}
array[low] = pivot;//将枢纽元素放回最终位置
return low;//返回存放枢纽的最终位置
}
}
结果是正确的