假设有n个记录,键值为k1,k2,...kn。利用分治策略与递归思想解决快速排序:
1.取i为第一个键值。
2.从左至右查找ki使得ki>k。
3.从右至左查找kj使得kj<k。
4.若i<j,swap(ki,kj),继续步骤2。
5.若i>j,swap(k,kj),并以j为基点分割为左右两部分,递归左右两部分进行排序(不包括j位置的键值)。
import java.util.Arrays;
public class QuickSorting {
public static void sort(int[] data, int low, int high) {
if (low >= high)
return;
int i = low;
int j = high;
int pivot = data[low];
while (i < j) {
while (i < high && data[i] <= pivot)
i++;
while (j > low && data[j] >= pivot)
j--;
if (i < j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
} else {
int temp = data[j];
data[j] = index;
data[low] = temp;
sort(data, low, j - 1);
sort(data, j + 1, high);
}
}
}
public static void quickSort(int[] data) {
sort(data, 0, data.length - 1);
}
public static void main(String[] args) {
int data[] = {10, 12, 3, 54, 5, 11, 7, 1};
quickSort(data);
System.out.println(Arrays.toString(data));
}
}
平均时间复杂度为O(nlogn),最坏O(n^2),最佳O(nlogn)。
平均空间复杂度为O(nlogn),最坏O(n),最佳O(logn)。
对主元改进后的算法如下,除了待排序数组全为相等元素时复杂度最差,其他情况皆为O(nlogn),还可以改进,改进的思路就是把pivot的位置放到数组末尾,在检测时当遇到与pivot相等时停止检测,等待交换。
package Sorting;//改进后的
import java.util.Arrays;
public class QuickSort {
private static int midOf3(int[] data, int low, int high) {
int mid = (low + high) / 2;
if (data[low] > data[mid])
swap(data, low, mid);
if (data[low] > data[high])
swap(data, low, high);
if(data[mid] > data[high])
swap(data, mid, high);
swap(data, low, mid);
return data[low];
}
private static void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
private static void sort(int[] data, int low, int high) {
int i = low;
int j = high;
if (low >= high)
return;
int pivot = midOf3(data, low, high);
while (i < j) {
while (i < high && data[i] <= pivot)
i++;
while (j > low && data[j] >= pivot)
j--;
if (i < j)
swap(data, i, j);
else {
swap(data, low, j);
sort(data, low, j - 1);
sort(data, j + 1, high);
}
}
}
private static void quickSort(int[] data) {
sort(data, 0, data.length - 1);
}
public static void main(String[] args) {
int[] data = { 8, 1, 4, 9, 7, 6};
quick_sort(data);
System.out.println(Arrays.toString(data));
}
}