为了账号安全,请及时绑定邮箱和手机立即绑定

三路快速排序法

标签:
算法

三路快速排序法

三路快速排序将数组分成了 <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);
		
	}
}





点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消