三种快速排序

本文详细介绍了快速排序的三种实现方式,包括适应不同重复元素情况的优化策略。第一种方式适用于元素不重复或重复较少的情况,第二种和第三种方式则通过改进分区策略来提高效率,特别是对于重复元素较多的数组。作者提供了具体的代码实现,并通过示例数组进行了排序演示。
摘要由CSDN通过智能技术生成
/**
 * 3种快排的实现方式,1是不适合重复元素多,2可以适应重复元素多,3可以优化重复元素多的时间
 */
/**
 * @author hxj 2020年7月27日
 */
public class Main {
	public static void quickSort(int[] arr) {
		if (arr == null || arr.length < 2) {
			return;
		}
		int L = 0, R = arr.length - 1;
		quickSort(arr, L, R);
	}

	private static void quickSort(int[] arr, int L, int R) {
		if (L >= R) {
			return;
		}
		//use partion1
//		int pivot = partition1(arr, L, R);
//		quickSort(arr, L, pivot - 1);
//		quickSort(arr, pivot + 1, R);
		
		//use partion2
		int[] bound = partition2(arr, L, R);
		quickSort(arr, L, bound[0]);
		quickSort(arr, bound[1], R);
		
		//use partition3
// 		int[] bound = partition3(arr, L, R);
// 		quickSort(arr, L, bound[0]);
// 		quickSort(arr, bound[1], R);

	}

	// 之所以要设计成取中点元素,是因为很多OJ都喜欢使用如{1 2 3 4 5}这样的数据去卡时间
	private static int partition1(int[] arr, int L, int R) {
		int num = arr[L + R >> 1];// 增加了center后可以随意取[L,R]中任意一个数
		int center = 0;// 为了记录等于num元素的下标
		int pivot = L - 1;
        // 注意是i = L, i<=R,不是i = 0, i <arr.length;
		for (int i = L; i <= R; i++) {
			if (arr[i] < num) {
				swap(arr, i, ++pivot);
			} else if (arr[i] == num) {
				swap(arr, i, ++pivot);
				center = pivot;
			}
		}
		swap(arr, center, pivot);

		return pivot;
	}

	private static int[] partition2(int[] arr, int L, int R) {
		int num = arr[L + (R - L >> 1)];// 可任取arr[0,arr.length)
        //int num = arr[(int) (L + Math.random() * (R - L + 1))];//随机快排
		int i = L, j = R;
		while (i <= j) {
			while (arr[i] < num) {
				i++;
			}
			while(arr[j] > num) {
				j--;
			}
			if(i <= j) {
				swap(arr, i++,j--);//注意要++,--
			}
		}
		
		return new int[] {j, i};//返回左区间边界和右区间边界
	}
	

	private static int[] partition3(int[] arr, int L, int R) {
		//只能取L或R,可以参照partition1修改成可以任意位置,或采用swap随机数
		int num = arr[L+(R-L>>1)];
		//如果num=arr[L],就要less = L, more = R+1;因为不让该数进行遍历
		int less = L-1, more = R+1;
		int i = L;
		while(i < more) {
			if(arr[i] < num) {
				swap(arr, ++less, i++);
			}else if(arr[i] > num) {
				swap(arr, --more, i);
			}else {
				i++;
			}
		}

		return new int[] {less, more};
	}

	
	private static void swap(int[] arr, int i, int j) {
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;

	}

	public static void main(String[] args) {
	    
	    int[] arr = {2, 4, 1, 5, 3, -1};
	    quickSort(arr);
	    for(int i = 0; i < arr.length; i++)
	        System.out.println(arr[i]);

	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值