快排

先讲经典快排。

荷兰国旗

从0 遍历到 n-1 ,num=5,第一个是 4 ,4 与 num 比较,当前数<= num ,把当前数,与小于等于区域中的下一个数交换。然后小于等于区域向右扩大一个位置。> num 的数,直接跳。

变种

有三个下标,一个是小于区域,一个是大于区域,一个是等于区域,叫 cur 。

遇到 cur =num,直接跳下一个。

 

遇到 cur < num,先和小于区域的下一个数交换,less + 1 ,cur +1.

遇到 cur > num 的数后,会与大于区域的前一个数交换。假设是 X ,然后大于区域向左移动一个位置,就是 more 向左移动一下。然后 cur 会停留在原地,考察这个 X 与 num 之间的大小关系。三种情况。

如果 cur 与 more 撞上 了,整个流程停止。(循环停止的条件)

 

 

 

 

开始一个数组,最后一个值作为划分值。

然后整个数组分为两个部分,<=X 的在左边,>=X 的在右边。

然后<=X 的当做一个全新的数组,再次把最后一个值当做划分值。两个部分拆分下去,让整个部分都有序。以上是经典快排。

 

改进:

 

4ae3df8a41db105230bfc89bab30a4f3641.jpg

=x 的部分不动,小于X 的区域和大于 X 的区域继续这样的过程——递归。

思路:

一个类三个方法,一个 quickSort 方法重载(判空,运行另一个重载方法),另一个 quickSort  方法重载(临界条件+接受 partition 方法的返回值+左右部分的递归)。

第二个方法是 swap 方法。

第三个方法是 partition 方法(返回的是一个数组,接受两个元素),设置小于大于的两个指针,less ,more 。while(L<more),三个 if 判断 L(cur)与 R (num) 的大小关系。最后交换边界值与 more 。最后返回一个只有两个元素的数组。

package suanfa;

public class quickSort {

	public static void quicksort(int[] arr) {   //重载
		if (arr == null || arr.length < 2) { 
			return;
		}
		quicksort(arr, 0, arr.length - 1);
	}

	public static void quicksort(int[] arr, int L, int R) { //默认在最后一个位置做划分,这个意思是num是最后一个值
		if (L < R) { // 临界条件
			//swap(arr,L+(int)(Math.random()*(R-L+1)),R);   这时一个随机快排
			int[] p = partition(arr, L, R);   //经过一个p过程,返回一个数组,是等于区域的左右两个边界
			quicksort(arr, L, p[0] - 1); // 左边部分继续递归
			quicksort(arr, p[1] + 1, R); // 右边部分继续递归
		}
	}

	public static int[] partition(int[] arr, int L, int R) {// 
		int less = L - 1; // less 是小于区域的 ,L 是 cur
		int more = R; // more 意思是 num 是最后一个值,R 与 num 复用了

		while (L < more) {   //循环条件,只要左边界<右边界,循环下去
			if (arr[L] < arr[R]) {
				swap(arr, ++less, L++);   //与 less 区域的下一个位置交换,
			} else if (arr[L] > arr[R]) {
				swap(arr, --more, L);
			} else {
				L++;
			}
		}
		swap(arr, more, R);  //边界代码一开始没有参与,最后要归位
		return new int[] { less + 1, more };   //返回一个数组
	}

	public 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 = { 0, 1, -94, 65, 888 };
		System.out.println(java.util.Arrays.toString(arr));
		quicksort(arr);
		System.out.println(java.util.Arrays.toString(arr));
	}

}

a4933e19712ff2f0eb0748ac5687d73f2a0.jpg

第二个重载方法中的停止循环的条件。小于区域<大于区域,停止。并且 if 逻辑贯穿整第二个 quickSort 方法。

patition中,声明了小于区域和大于区域。L < more,不是 < R ,因为 more 才是大于区域,R 是只是右边界。cur < more ,循环一直执行。

return 返回 new int[]{ less+1,more},  是等于区域的边界。

 

 

转载于:https://my.oschina.net/u/3973793/blog/3099567

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值