基本思路
-以一个数作为标志,将序列分为两部分
-v:标志
-J:分界标志
-e:正在访问的标志
代码实现
-复杂度(Nlog(N))
import helper.SortTestHleper;
public class QuickSort {
public static <T extends Comparable<? super T>> void quickSort(T[] arr, int n) {
sonOfQuickSort(arr, 0, n - 1);
}
// 对arr[l...r]部分进行快速排序
private static <T extends Comparable<? super T>> void sonOfQuickSort(T[] arr, int l, int r) {
if (l >= r)
return;
int index = partition(arr, l, r);
sonOfQuickSort(arr, l, index - 1);
sonOfQuickSort(arr, index + 1, r);
}
// 对arr[l...r]部分进行partition分治操作,返回值是作为分界点
private static <T extends Comparable<? super T>> int partition(T[] arr, int l, int r) {
T v = arr[l];
// arr[l+1..j]<v;arr[j+1..i) > v
int j = l;
for (int i = l + 1; i <= r; i++) {
if (arr[i].compareTo(v) < 0) {
T temp;
temp = arr[i];
arr[i] = arr[j + 1];
arr[j + 1] = temp;
j++;
}
}
T tmp;
tmp = arr[l];
arr[l] = arr[j];
arr[j] = tmp;
return j;
}
public static void main(String[] args) {
int n = 1000000;
// 生成随机数组
Integer[] a = SortTestHleper.generateRandomArray(n, 0, n);
// 调用测试方法
SortTestHleper.testSort(a, a.length);
}
}
-数组大小为100000的情况下输出结果
归并排序算法消耗时间53328ms
快速排序算法消耗时间448ms
优化
-高级的排序算法到底层时可以采用插入的排序算法进行优化
if (r - l <= 15) {
// 当分块中元素为15+1时,换成插入排序
SelectionSort.insertionSort(arr,r,l);
return;
}
归并排序算法消耗时间50327ms
快速排序算法消耗时间374ms
与归并排序比较
-归并排序子数组比较均匀
-快速排序子数组很大情况下为一大一小,平衡度差
-快速排序树的高度没办法保证
-当数组完全有序时会退化为O(n^2)
-随机采用元素做标记元素可以使得时间复杂度期望值为O(Nlog(N))
采用随机标记元素法进行优化
private static <T extends Comparable<? super T>> int partition(T[] arr, int l, int r) {
// 随机生成位置
int s = (int) (Math.random() * (r - l + 1)) + l;
T temp1;
temp1 = arr[s];
arr[s] = arr[l];
arr[l] = temp1;
T v = arr[l];
// arr[l+1..j]<v;arr[j+1..i) > v
int j = l;
for (int i = l + 1; i <= r; i++) {
if (arr[i].compareTo(v) < 0) {
T temp2;
temp2 = arr[i];
arr[i] = arr[j + 1];
arr[j + 1] = temp2;
j++;
}
}
T tmp;
tmp = arr[l];
arr[l] = arr[j];
arr[j] = tmp;
return j;
}
-优化后结果
归并排序算法消耗时间46975ms
快速排序算法消耗时间324ms