几种快速排序的几点疑问

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

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

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值