继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

三路快速排序法

郭富县城
关注TA
已关注
手记 3
粉丝 0
获赞 1

三路快速排序法

三路快速排序将数组分成了 <V, ==V, >V 三部分,这样只需递归的对<V和>V的部分进行快速排序


具体步骤演示:

处理e的各种情况

e == v, i++


e < v,  e 和 arr[lt + 1] 交换, lt++, i++查看下一个元素


e > v, e 和 arr[gt - 1] 交换位置, gt--

当 i == gt : 表示对整个数组处理完毕

交换arr[l]和arr[lt], lt++

接下来只需对<v的部分和>v的部分进行递归排序就好了, ==v的部分已经放在了数组中合适的位置

这种方案的优点:不需对大量==v 的元素进行排序操作

快速排序和归并排序都是Nlog(N),但是快速排序比归并排序要快些


代码部分

public class ThreeWayQuickSort extends Sort {
	
	private Random random;
	
	public void sort(int[] arr, int n) {
		random = new Random(new Date().getTime());
		quickSort(arr, 0, n - 1);
	}
	
	/**
	 * 对arr[l..r]部分进行三路快速排序
	 * 将arr[l..r]分为<v, ==v, >v 三部分
	 * 然后递归对<v 和 >v 部分进行三路快速排序
	 */
	private void quickSort(int[] arr, int l, int r) {
		if (l >= r) {
			return;
		}
		if ( r - l <= 15) {//优化1:子序列元素个数小于16时用插入排序
			AlgorithmUtils.insertionSort(arr, l, r);
			return;
		}
		//由于三路快速排序的中间部分是==v的一个区间,java语言不好写出返回区间首尾的值,
		//所以不单独写partition方法
		AlgorithmUtils.swap(arr, l, Math.abs(random.nextInt()) % (r - l + 1) + l);
		int v = arr[l];
		int lt = l; //arr[l + 1..lt] < v //初始时 lt < l + 1, 为空区间
		int i = l + 1; //arr[lt + 1..i - 1] == v
		int gt = r + 1; //arr[gt..r] > v //初始时 r < gt , 为空区间
		while (i < gt) { 
			if (arr[i] < v) {
				AlgorithmUtils.swap(arr, i, lt + 1);
				lt++;
				i++;
			}else if (arr[i] > v) {
				AlgorithmUtils.swap(arr, i, gt - 1);
				gt--;
			}else {
				i++;
			}
		}
		
		AlgorithmUtils.swap(arr, l, lt);
		
		quickSort(arr, l, lt - 1);
		quickSort(arr, gt, r);
		
	}
}





打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP