您的位置:首页 > 其它

快速排序要交换等值元素的原因

2016-09-20 15:40 330 查看
简单来说是为了防止重复元素过多时,即有很多元素与切分元素相等时,切分的效率过低(每次切分时左右部分元素数相差过多),导致比较次数过多。

测试代码如下:

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的数组,效率很低。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  快速排序