[Java]快速排序,以及双基快排

/**
 * 单基准快排
 * 使用 quickSort(arr,0,arr.length-1) 排序整个数组
 */
private static void quickSort(int[] arr, int left, int right) {
	//判断排序条件
	if (right <= left)
		return;
	// 范围内只有两个元素时直接交换
	if (right == left + 1) {
		if (arr[left] > arr[right]) {
			swap(arr, left, right);
		}
		return;
	}
	//lt的左边放小于基准值的值
	//gt的右边放大于基准值的值
	//lt与gt其中一个是基准值
	int lt = left, gt = right;
	//基准值位置,初始在lt位置
	boolean atLt = true;
	//从两侧向中心并拢
	while (lt < gt) {
		//如果左侧大于右侧
		if (arr[lt] > arr[gt]) {
			//交换位置
			swap(arr, lt, gt);
			//交换基准值位置
			atLt = !atLt;
		}
		//基准值在左侧,则右侧遍历,否则相反
		if (atLt)
			--gt;
		else
			++lt;
	}
	//继续排序被基准值分隔的两部分
	quickSort(arr, left, lt - 1);
	quickSort(arr, gt + 1, right);
}
/**
 * 双基准快排
 * 使用 dualPivotQuickSort(arr,0,arr.length-1) 排序整个数组
 */
public static void dualPivotQuickSort(int[] arr, int left, int right) {
	// 判断排序条件
	if (right <= left)
		return;
	// 范围内只有两个元素时直接交换
	if (right == left + 1) {
		if (arr[left] > arr[right]) {
			swap(arr, left, right);
		}
		return;
	}
	// left与right分别为左右基准下标(循环时不会改变其下标)
	// 使[right]>[left]
	if (arr[left] > arr[right]) {
		swap(arr, left, right);
	}
	int lt = left + 1; // 小于left的放在lt左边
	int gt = right - 1;// 大于right的放在gt右边
	int i = lt; // 循环索引
	while (i <= gt) {
		if (arr[i] < arr[left]) {
			// 小于左基准,放在lt左边
			swap(arr, i++, lt++);
		} else if (arr[i] > arr[right]) {
			// 大于右基准,放在gt右边
			swap(arr, i, gt--);
		} else {
			// 放在lt与i之间
			++i;
		}
	}
	// 将基准交换到位,
	swap(arr, left, lt - 1);
	swap(arr, right, gt + 1);
	// 继续将被两个基准值分成的三部分排序
	// 此时左基准下标 lt-1 右基准下标 gt+1
	dualPivotQuickSort(arr, left, lt - 2);
	dualPivotQuickSort(arr, gt + 2, right);
	dualPivotQuickSort(arr, lt, gt);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值