快速排序要交换等值元素的原因
2016-09-20 15:40
330 查看
简单来说是为了防止重复元素过多时,即有很多元素与切分元素相等时,切分的效率过低(每次切分时左右部分元素数相差过多),导致比较次数过多。
测试代码如下:
a方式交换等值元素,b方式不交换等值元素。compare_x为方式x比较次数,exchange_x为x方式交换次数。比如输入一个极端的例子,输入为“8 1 1 1 1 1 1 1 1”,即8个等值元素,程序的输出如下:
可以看到b方式比较次数远高于a方式的比较次数,而交换次数只少了一点点。原因很简单,a方式每次都能较为平均的将数组切分,这样能达到最高的效率;而b方式正相反,每次切分都会产生一个长度为0的数组,效率很低。
测试代码如下:
package helloworld; import java.util.Arrays; import java.util.Scanner; public class Quick { public static int compare_a = 0; public static int exchange_a = 0; public static int compare_b = 0; public static int exchange_b = 0; public static void sort_a(Integer[] a, int lo, int hi) { if (lo >= hi) { return; } int mid = partition_a(a, lo, hi); sort_a(a, lo, mid - 1); sort_a(a, mid + 1, hi); } public static int partition_a(Integer[] a, int lo, int hi) { int v = a[lo]; int i = lo; int j = hi + 1; while (i < j) { compare_a++; while (a[++i] < v) { if (i >= hi) { break; } compare_a++; } compare_a++; while (a[--j] > v) { if (j <= lo) { break; } compare_a++; } if (i < j) { exchange_a++; int temp = a[i]; a[i] = a[j]; a[j] = temp; } } exchange_a++; int temp = a[j]; a[j] = v; a[lo] = temp; return j; } public static void sort_b(Integer[] a, int lo, int hi) { if (lo >= hi) { return; } int mid = partition_b(a, lo, hi); sort_b(a, lo, mid - 1); sort_b(a, mid + 1, hi); } public static int partition_b(Integer[] a, int lo, int hi) { int v = a[lo]; int i = lo; int j = hi + 1; while (i < j) { compare_b++; while (a[++i] <= v) { if (i >= hi) { break; } compare_b++; } compare_b++; while (a[--j] >= v) { if (j <= lo) { break; } compare_b++; } if (i < j) { exchange_b++; int temp = a[i]; a[i] = a[j]; a[j] = temp; } } exchange_b++; int temp = a[j]; a[j] = v; a[lo] = temp; return j; } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n; while (in.hasNext()) { exchange_a = 0; exchange_b = 0; compare_a = 0; compare_b = 0; n = in.nextInt(); Integer[] a = new Integer ; for (int i = 0; i < n; i++) { a[i] = in.nextInt(); } Integer[] b = Arrays.copyOf(a, a.length); sort_a(a, 0, a.length - 1); sort_b(b, 0, b.length - 1); System.out.format("%-12s%-12s%-12s\n", "", "a", "b"); System.out.format("%-12s%-12d%-12d\n", "compare", compare_a, compare_b); System.out.format("%-12s%-12d%-12d\n", "exchange", exchange_a, exchange_b); } in.close(); } }
a方式交换等值元素,b方式不交换等值元素。compare_x为方式x比较次数,exchange_x为x方式交换次数。比如输入一个极端的例子,输入为“8 1 1 1 1 1 1 1 1”,即8个等值元素,程序的输出如下:
a b compare 18 63 exchange 9 7
可以看到b方式比较次数远高于a方式的比较次数,而交换次数只少了一点点。原因很简单,a方式每次都能较为平均的将数组切分,这样能达到最高的效率;而b方式正相反,每次切分都会产生一个长度为0的数组,效率很低。
相关文章推荐
- 快速排序
- C#快速排序算法实例分析
- C#递归算法之快速排序
- C 语言快速排序实例代码
- C++快速排序的分析与优化详解
- php快速排序原理与实现方法分析
- js实现数组冒泡排序、快速排序原理
- php简单实现快速排序的方法
- Java 快速排序(QuickSort)原理及实现代码
- 快速排序和分治排序介绍
- java 算法之快速排序实现代码
- Java实现快速排序算法(Quicktsort)
- Java中的数组排序方式(快速排序、冒泡排序、选择排序)
- 快速排序的原理及java代码实现
- C/C++实现快速排序的方法
- c语言实现冒泡排序、希尔排序等多种算法示例
- 深入单链表的快速排序详解
- C++实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等
- JavaScript实现快速排序的方法
- 逐步讲解快速排序算法及C#版的实现示例