三種快速排序

qq_43560633發表於2020-10-30
/**
 * 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]);

	}

}

相關文章