快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。
参考地址:维基百科
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
1、源代码
/** * 数据结构上学的快速排序 * * @param array * 待排序数组 * @param left * 左边序号 * @param right * 右边序号 */ public static void quickSortInDataStructure(int[] array, int left, int right) { if (left < right) { int key = array[left]; int low = left; int high = right; while (low < high) { while (low < high && array[high] >= key) { high--; } while (low < high && array[low] <= key) { low++; } if (low < high) { int temp = array[low]; array[low] = array[high]; array[high] = temp; } } array[left] = array[low]; array[low] = key; System.out.println("键Key:" + key + ",结果:" + Arrays.toString(array)); quickSortInDataStructure(array, left, low - 1); quickSortInDataStructure(array, low + 1, right); } }
2 测试代码
@Test public void testQuickSortInDataStructure() { int[] array = { 1, 8, 3, 5, 4, 6, 2, 7, 9 }; int[] expectResult = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Sort.quickSortInDataStructure(array, 0, array.length - 1); Assert.assertArrayEquals(expectResult, array); }
3 结果
键Key:1,结果:[1, 8, 3, 5, 4, 6, 2, 7, 9]
键Key:8,结果:[1, 7, 3, 5, 4, 6, 2, 8, 9]
键Key:7,结果:[1, 2, 3, 5, 4, 6, 7, 8, 9]
键Key:2,结果:[1, 2, 3, 5, 4, 6, 7, 8, 9]
键Key:3,结果:[1, 2, 3, 5, 4, 6, 7, 8, 9]
键Key:5,结果:[1, 2, 3, 4, 5, 6, 7, 8, 9]
4 封装
4.1 封装java代码
package better.amy.sort; import java.util.Comparator; import java.util.Random; /** * 快速排序 * * @author zhujinrong * */ public class QuickSort { /** * 随机 */ public static final Random RND = new Random(); /** * array[i]和array[j]进行交换 * * @param array * @param i * @param j */ private static void swap(Object[] array, int i, int j) { Object temp = array[i]; array[i] = array[j]; array[j] = temp; } /** * 找到中轴 * * @param array * @param begin * @param end * @param cmp * @return 中轴位置 */ private static <E> int partition(E[] array, int begin, int end, Comparator<? super E> cmp) { int index = begin + RND.nextInt(end - begin + 1); E pivot = array[index]; swap(array, index, end); for (int i = index = begin; i < end; ++i) { if (cmp.compare(array[i], pivot) <= 0) { swap(array, index++, i); } } swap(array, index, end); return (index); } /** * 快速排序 * * @param array * @param begin * @param end * @param cmp */ private static <E> void qsort(E[] array, int begin, int end, Comparator<? super E> cmp) { if (begin < end) { int index = partition(array, begin, end, cmp); qsort(array, begin, index - 1, cmp); qsort(array, index + 1, end, cmp); } } /** * 快速排序入口 * * @param array * @param cmp */ public static <E> void sort(E[] array, Comparator<? super E> cmp) { qsort(array, 0, array.length - 1, cmp); } }
这个是在维基百科上的代码,我觉得写得非常好,以至于我把它补到这里来了。
4.2 测试代码
@Test public void test100() { Integer [] array1 = new Integer[100]; Integer [] array2 = new Integer[100]; for(int i = 0; i < 100; i++) { array1[i] = new Random().nextInt(101); array2[i] = array1[i]; } QuickSort.sort(array1, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { // TODO Auto-generated method stub return o1.intValue() - o2.intValue(); } }); Arrays.sort(array2); Assert.assertArrayEquals(array2, array1); }
5 总结与分析
1、写java要有面向对象的思维跟封装特性,别脱不了C语言的想法。
2、我看数据结构的算法和java面向对象的算法,有一点不同,就是在找中轴的位置的时候,一个是挨着找,一个是随机找的。这个我再看看两者有什么不同。