快速排序和歸併排序
阿新 • • 發佈:2019-01-09
分而治之(divide - conquer);每個遞迴過程涉及三個步驟
第一, 分解: 把待排序的 n 個元素的序列分解成兩個子序列, 每個子序列包括 n/2 個元素.
第二, 治理: 對每個子序列分別呼叫歸併排序MergeSort, 進行遞迴操作
第三, 合併: 合併兩個排好序的子序列,生成排序結果.
/**
* 分治演算法思路: 將一個大問題,分解成同樣的多個小問題,解決每個小問題,最後合併就解決了大問題。
* @param arr
* @param low
* @param high
*/
public static void mergeSort(int arr[], int low, int high) {
int midle = (low + high) >>> 1;
if (low < high) { // 控制至少兩個才能分解合併
// 分解
mergeSort(arr, low, midle);
mergeSort(arr, midle + 1, high);
//合併
merge(arr, low, midle, high);
}
}
// 合併
public static void merge(int arr[], int low, int midle, int high) {
int center = midle + 1; // 右邊陣列的起始位置
int temp[] = new int[high - low + 1]; // 臨時陣列
int index = 0;
while (low <= midle && center <= high) {
if (arr[low] < arr[center]) {
temp[index++] = arr[low++];
} else if (arr[low] > arr[center]) {
temp[index++] = arr[center++];
} else {
temp[index++] = arr[low++];
temp[index++] = arr[center++];
}
}
while (low <= midle) { // 左邊還有剩餘
temp[index++] = arr[low++];
}
while (center <= high) { // 右邊還有剩餘
temp[index++] = arr[center++];
}
copy(arr, temp, high); // 拷貝元素
}
public static void copy(int arr[], int temp[], int high) {
for (int i = temp.length - 1; i >= 0; i--) {
arr[high--] = temp[i];
}
}
快速排序是氣泡排序的改進版,也是最好的一種內排序,在很多面試題中都會出現,也是作為程式設計師必須掌握的一種排序方法。
思想:1.在待排序的元素任取一個元素作為基準(通常選第一個元素,但最的選擇方法是從待排序元素中隨機選取一個作為基準),稱為基準元素;
2.將待排序的元素進行分割槽,比基準元素大的元素放在它的右邊,比其小的放在它的左邊;
3.對左右兩個分割槽重複以上步驟直到所有元素都是有序的。
所以我是把快速排序聯想成東拆西補或西拆東補,一邊拆一邊補,直到所有元素達到有序狀態。
/**
*
* void QuickSort(SeqList R,int low,int high) {
int pivotpos; //劃分後的基準記錄的位置
if(low<high){ //僅當區間長度大於1時才須排序
pivotpos=Partition(R,low,high); //對R[low..high]做劃分
QuickSort(R,low,pivotpos-1); //對左區間遞迴排序
QuickSort(R,pivotpos+1,high); //對右區間遞迴排序
}
}
*/
public static void quickSort(int low, int high, int arr[]) {
int position;
if (low < high) {
position = partition(arr, low, high);
quickSort(low, position-1, arr);
quickSort(position+1, high, arr);
}
}
private static int partition(int arr[], int low, int high) {
int res = arr[low];
while (low != high) {
while (low < high && arr[high] >= res) {
high--;
}
arr[low] = arr[high];
while (low < high && arr[low] <= res) {
low++;
}
arr[high] = arr[low];
}
arr[low] = res; // 基數歸位
return low;
}