标签:
快速排序的时间复杂度为O(n2),但其平均性能很好,其期望复杂度为O(nlog2n),并且其中隐含的常数因子很小。
对输入数组A[p..r],将其划分为两个子数组A[p..q-1]和A[q+1..r],其中A[q]满足,A[q]大于等于任意一个属于A[p..q-1]的元素,小于等于任意一个属于A[q+1..r]的元素。递归划分左右两个子数组,最终就可以得到排序后的数组。其算法如下:
sort(array) sort(array, 0, array.length-1) sort(array, start, end) if start < end q = partition(array, start, end) sort(array, start, q-1) sort(array, q+1, end)
其中partition分解过程中找到q的位置,其算法如下:
partition(array, start, end) i = start - 1 for j = start to end-1 if array[j] <= array[end] i++ if i != j exchange array[i] with array[j] i++ exchange array[i] with array[end] return i
partition算法解析:
(1)将最后一个元素作为主元,由于最开始待划分的两个子数组的大小为0,因此定义分隔位置i的值为start-1,i表示第一个子数组的最后一个元素,而i+1表示分隔的位置。
(2)围绕主元对start和end-1内的元素进行划分,如果小于等于主元,第一个子数组的大小加1,即分隔位置加1。此时由于a[j]小于主元,因此将其交换到i指示的位置。
(3)最后,分隔位置加1,此时为第二个数组的第一个位置,将其与主元交换后,这个位置就变成了正确的分隔位置。
这样在每一次执行partition之后,所有i左侧的元素均小于等于array[i],i右侧的元素大于等于array[i],而array[i]找到了它在数组中的正确位置。
实例的推导过程(参考《算法导论 第三版》)如下图:
java实现
package com.diysoul.algorithm.sort; import java.util.Random; public class QuickSort { public static void sort(int[] array) { sort(array, 0, array.length - 1); } public static void sort(int[] array, int start, int end) { if (start < end) { int p = partition(array, start, end); sort(array, start, p - 1); sort(array, p + 1, end); } } public static int partition(int[] array, final int start, final int end) { // 增加随机主元,仅测试,实际工作中删除 // Random random = new Random(); // int pos = random.nextInt(end - start + 1) + start; // if (pos != end) { // int temp = array[end]; // array[end] = array[pos]; // array[pos] = temp; // } int i = start - 1; for (int j = start; j <= end - 1; j++) { if (array[j] < array[end]) { i++; if (i != j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } } } i++; int temp = array[i]; array[i] = array[end]; array[end] = temp; return i; } public static void main(String[] args) { int maxSize = 10000; int min = -10000; int max = 10000; Random random = new Random(); int[] a = new int[maxSize]; for (int i = 0; i < a.length; i++) { a[i] = random.nextInt(max - min) + min; } print(a); sort(a); print(a); checkSort(a); } private static void checkSort(int[] array) { if (array == null || array.length == 0) return; for (int i = 1; i < array.length; i++) { if (array[i - 1] > array[i]) { System.out.println("Error! Array is not sorted in index " + i); break; } } } private static void print(int[] array) { if (array == null || array.length == 0) return; System.out.print("quick sort array(" + array.length + "): "); int i = 0; for (; i < array.length - 1; i++) { System.out.print(array[i] + ", "); } System.out.println(array[i]); } }
标签:
原文地址:http://www.cnblogs.com/diysoul/p/5673050.html