Java快速排序和歸併排序區別和實現
快速排序與歸併排序的概念:
快速排序(Quicksort)是對氣泡排序的一種改進。 快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。 歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱為二路快速排序與歸併排序的區別:
快速排序的時間複雜度是O (nlogn),但是快速排序是一種不穩定的排序方法,也就是說當有多個相同的值的時候在排序結束的時候它們的相對位置會發生改變。
歸併排序的時間複雜度是O (nlogn),但是歸併排序是一種穩定的排序方法,即相等的元素順序不會改變,但是相比於快速排序來說歸併要申請的空間更大,消耗空間更多。
快速排序實現方式:
快速排序原理基於氣泡排序改進的。設要排序的陣列是A[0]....A[N-1],首先任意選取一個數據(通常選取用陣列的第一個數)作為關鍵資料key,然後比key小的資料都放到key的前面,比key大的資料都放在key的後面,這個過程稱為一趟快速排序。
演算法思路:
1>設定兩個變數i,j,排序開始的時候,i=low;j = high;(第一趟low=0,high為陣列長度N)
2>以第一個陣列元素為關鍵元素,賦值給key,即key = A[0];
3>從j開始像前搜尋,找到第一個比key小的數a[j],將a[j]和a[i]交換。
4>從i開始向後搜素,找到第一個比key大的數a[i],將a[i]和a[j]交換。
5>重複3,4步直到i==j
6>對key左邊和右邊分別遞迴呼叫以上步驟。
程式碼如下:
package sort;
import java.util.Arrays;
import java.util.Scanner;
public class QuickSort {
public static void main(String[] args) {
int [] a = {1,11,2,3,5,68,0,1};
System.out.println("未排序的陣列:"+Arrays.toString(a));
if(a.length > 0){
quickSort(a,0,a.length-1);
}else{
System.out.println("空陣列不能排序");
}
System.out.println("排序後的陣列:"+Arrays.toString(a));
}
public static void quickSort(int[] a,int low,int high){
if(low > high){
return;
}//遞迴的出口
int i = low;
int j = high;
int key = a[low];
while(i < j){
while(a[j] > key && i < j){
j--;
}//找到第一個比key小的數
while(a[i] <= key && i < j){
i++;
}//找到第一個比key大的數
if(i < j){//如果i小於j,交換a[i],a[j]
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
int p = a[i];
a[i] = a[low];
a[low] = p;//調整key的位置
quickSort(a,low,i-1);
quickSort(a,i+1,high);
}
}
歸併排序的實現方式:
歸併排序就是利用歸併的思想實現的排序方法。而且充分利用了完全二叉樹的深度是log2n+1的特性,因此效率比較高。 基本原理如下:對於給定的一組記錄,利用遞迴與分治技術將資料序列劃分成為越來越小的半子表,在對半子表排序,最後再用遞迴方法將排好序的半子表合併成為越來越大的有序序列。經過第一輪比較後得到最小的記錄,然後將該記錄的位置與第一個記錄的位置交換;接著對不包括第一個記錄以外的其他記錄進行第二次比較,得到最小記錄並與第二個位置記錄交換;重複該過程,知道進行比較的記錄只剩下一個為止。
實現方式:第一步:申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列第二步:設定兩個指標,最初位置分別為兩個已經排序序列的起始位置第三步:比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置第四步:重複步驟3直到某一指標超出序列尾將另一序列剩下的所有元素直接複製到合併序列尾。
package sort;
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args){
int [] a = {1,11,2,3,5,68,0,1};
System.out.println("未排序的陣列:"+Arrays.toString(a));
if(a.length > 0){
mergeSort(a,0,a.length-1);
}else{
System.out.println("空陣列不能排序");
}
System.out.println("排序後的陣列:"+Arrays.toString(a));
}
public static void merge(int[]a,int low,int mid,int high){
int [] mergeArr = new int[high-low+1];//申請一個新空間來儲存排序後陣列
int i = low;
int j = mid + 1;
int k = 0;
while(i <= mid && j <= high){
if(a[i] < a[j]){
mergeArr[k] = a[i];
k++;
i++;
}else{
mergeArr[k] = a[j];
k++;
j++;
}
}
while(i <= mid){
mergeArr[k] = a[i];
k++;
i++;
}//把左邊剩餘的元素匯入
while(j <= high){
mergeArr[k] = a[j];
j++;
k++;
}//把右邊剩餘的元素匯入
for(int m = 0;m < mergeArr.length;m++){
a[m+low] = mergeArr[m];
}//將新排好序的陣列放入元素相應的位置中
}
public static void mergeSort(int []a,int low,int high){
int mid = (low + high) / 2;
if(low < high){
mergeSort(a,low,mid);//左
mergeSort(a,mid+1,high);//右
merge(a,low,mid,high);//左右合併
}
}
}
以上就是我對快速排序演算法和歸併演算法學習的心得,如有不足還多多請各位指教。