我的小快排(兩種分割方法)

今天看到微博上有人轉一篇文章,題目是《你問什麼寫不好快排》,看看自己多長時間能把快排寫出來。結果,果然20分鐘沒寫出來,本來以爲明白原理,結果實現的出現各種問題,小 bug。最終花了半個點,寫出來了,就是下面代碼中 partition版本的。後來又翻了下算法導論,看到上面的快排,寫了第二個分割子函數 partition2,這個原理更加清楚,用的是一個循環不變式的原理,將數組劃分爲了四個區域,具體說明可以參照算法導論。下面貼下代碼,自己mark 一下。


算法導論上partition過程的僞代碼如下

partition(A,p,r)
    x <- A[r]
    i <- p - 1
    for j <- p to r - 1
        do if A[j] <= x
            then i <- i +1
                exchange A[i] <-> A[j]
    exchange A[i+1] <-> A[r]
    return i+1


對於循環的每一輪迭代的開始,對於任何數組下標k,有

1)  如果 p <= k <= i,則 A[k] <= x

2)  如果 i + 1 <= k <= j - 1,則A[k] > x

3) 如果k = r,則 A[k] = x


package com.deron.business;

/**
 * this is quick sort tool class
 * 
 * @author deron
 * 
 */

public class QSort {
	public static void qSort(int[] array) {
		qSort(array, 0, array.length - 1);
	}

	public static void qSort(int[] array, int start, int end) {
		if (start < end) {
			int t = partition2(array, start, end);
			qSort(array, start, t - 1);
			qSort(array, t + 1, end);
		}
	}

	public static int partition(int[] array, int start, int end) {
		int t = start;
		int lp = start + 1;
		int rp = end;

		while (lp < rp) {
			while (array[lp] <= array[t] && lp < rp)
				lp++;
			while (array[rp] >= array[t] && lp < rp)
				rp--;
			if (lp < rp) {
				int tmp = array[lp];
				array[lp] = array[rp];
				array[rp] = tmp;
				lp++;
				rp--;
			}
		}
		if (array[lp] <= array[t]) {
			int tmp = array[t];
			array[t] = array[lp];
			array[lp] = tmp;
			t = lp;
		} else {
			int tmp = array[t];
			array[t] = array[lp - 1];
			array[lp - 1] = tmp;
			t = lp - 1;
		}
		
		return t;
	}
	
	public static int partition2(int[] array, int start, int end) {
		int v = array[start];
		int lp = start;
		int rp = start + 1;
		for (; rp <= end; rp++) {
			if (array[rp] <= v) {
				lp++;
				int tmp = array[lp]; 
				array[lp] = array[rp];
				array[rp]= tmp; 
			}
		}
		
		array[start] = array[lp];
		array[lp]= v; 
		
		return lp;
	}
}


發佈了53 篇原創文章 · 獲贊 15 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章