几种快速排序的几点疑问

来源:互联网 发布:麻瓜网络 编辑:程序博客网 时间:2024/06/10 08:13

大学学的快速排序,现在已经忘了,重新学一遍.

最近学习了一篇快速排序的文章:

http://www.importnew.com/8445.html#comment-13445

发现里面双基准排序有点问题.修正如下:

package test;import java.util.Arrays;public class QuickSortDualPivot extends QuickSort {public static void main(String[] args) {int[] arr = new int[] { 3, 4, 2, 1, 3 };QuickSortDualPivot test = new QuickSortDualPivot();System.out.println(Arrays.toString(arr));test.sort(arr);System.out.println(Arrays.toString(arr));}public void sort(int[] input) {sort(input, 0, input.length - 1);}private void sort(int[] input, int lowIndex, int highIndex) {if (highIndex <= lowIndex)return;int pivot1 = input[lowIndex];int pivot2 = input[highIndex];if (pivot1 == pivot2) {int temI = lowIndex;while (pivot1 == pivot2 && temI < highIndex) {temI++;pivot1 = input[temI];}exchange(input, lowIndex, temI);}if (pivot1 > pivot2) {exchange(input, lowIndex, highIndex);pivot1 = input[lowIndex];pivot2 = input[highIndex];}int i = lowIndex + 1;int lt = lowIndex + 1;int gt = highIndex - 1;while (i <= gt) {if (less(input[i], pivot1)) {exchange(input, i++, lt++);} else if (less(pivot2, input[i])) {exchange(input, i, gt--);} else {i++;}}exchange(input, lowIndex, --lt);exchange(input, highIndex, ++gt);sort(input, lowIndex, lt - 1);sort(input, lt + 1, gt - 1);sort(input, gt + 1, highIndex);}}


用以下代码测试耗时:

int RANGE = 1000;int SIZE = 1000 * 10000;int[] data = new int[SIZE];Random rdm = new Random();for (int i = 0; i < SIZE; i++) {data[i] = rdm.nextInt() % RANGE;}int[] tem = Arrays.copyOf(data, data.length);long start = System.currentTimeMillis();new QuickSortBasic().sort(tem);System.out.println("basic:" + (System.currentTimeMillis() - start));tem = Arrays.copyOf(data, data.length);start = System.currentTimeMillis();new QuickSort3Way().sort(tem);System.out.println("3 way:" + (System.currentTimeMillis() - start));tem = Arrays.copyOf(data, data.length);start = System.currentTimeMillis();new QuickSortDualPivot().sort(tem);System.out.println("dual privot:" + (System.currentTimeMillis() - start));

结果大约是:

RANGE/SIZE

100,000/10,000,000
basic:1150
3 way:1006
dual privot:1382

1,000/10,000,000
basic:1009
3 way:679
dual privot:23569

100/10,000,000
basic:949
3 way:430
Exception in thread "main" java.lang.StackOverflowError

1,000,000/1,000,000

basic:151
3 way:147
dual privot:115

发现在重复数据多的时候,还是三路快速排序效率高.双基准排序只有在重复数据不够多的情况下效率才会超过三路排序.

对这些算法不是很熟.只是根据那篇文章学到的.如果有问题,就评论一下.谢谢!


下面把剩下两个算法记一下,以便以后学习:

快速排序基本排序:

package test;public class QuickSortBasic extends QuickSort {public void sort(int[] input) {sort(input, 0, input.length - 1);}private void sort(int[] input, int lowIndex, int highIndex) {if (highIndex <= lowIndex) {return;}int partIndex = partition(input, lowIndex, highIndex);sort(input, lowIndex, partIndex - 1);sort(input, partIndex + 1, highIndex);}private int partition(int[] input, int lowIndex, int highIndex) {int i = lowIndex;int pivotIndex = lowIndex;int j = highIndex + 1;while (true) {while (less(input[++i], input[pivotIndex])) {if (i == highIndex)break;}while (less(input[pivotIndex], input[--j])) {if (j == lowIndex)break;}if (i >= j)break;exchange(input, i, j);}exchange(input, pivotIndex, j);return j;}}


快速排序三路排序:

package test;public class QuickSort3Way extends QuickSort {public void sort(int[] input) {sort(input, 0, input.length - 1);}public void sort(int[] input, int lowIndex, int highIndex) {if (highIndex <= lowIndex)return;int lt = lowIndex;int gt = highIndex;int i = lowIndex + 1;int pivotIndex = lowIndex;int pivotValue = input[pivotIndex];while (i <= gt) {if (less(input[i], pivotValue)) {exchange(input, i++, lt++);} else if (less(pivotValue, input[i])) {exchange(input, i, gt--);} else {i++;}}sort(input, lowIndex, lt - 1);sort(input, gt + 1, highIndex);}}


0 0
原创粉丝点击