本文我準備用Java實現歸併排序。具體的排序算法過程已經在註釋裏面了,大家可以複製代碼到IDE裏面,用DEBUG模式研究算法的過程(算法參考:https://blog.csdn.net/qq_36442947/article/details/81612870):
import java.util.Arrays;
import java.util.Random;
/**
* @author LiYang
* @ClassName MergeSort
* @Description 歸併排序算法
* @date 2019/11/4 16:50
*/
public class MergeSort {
/**
* 歸併排序算法(MergeSort)
* 本算法會分解數組到左右都只有1個元素的子數組(肯定有序),
* 然後歸併爲2個元素的子數組(已經有序),然後又歸併爲
* 4個元素的子數組(已經有序)……直到全部待排序數組
* @param arr 待排序的數組
* @param left 起始下標
* @param right 終止下標
*/
public static void mergeSort(int [] arr, int left, int right){
//當子序列中只有一個元素時,也就是left = right時,結束遞歸
if(left < right){
//將當前數組分爲兩個子數組的分界線
int mid = (left + right) / 2;
//對左側子數組進行遞歸歸併排序
mergeSort(arr, left, mid);
//對右側子數組進行遞歸歸併排序
mergeSort(arr, mid + 1, right);
//歸併左右側子序列
merge(arr, left, mid, right);
}
}
/**
* 歸併排序算法的歸併操作,將兩個有序數組歸併爲一個排序數組
* @param arr 歸併前的數組,包含左右兩個有序數組
* @param left 左邊界
* @param mid 兩個有序數組的分隔下標
* @param right 右邊界
*/
public static void merge(int[] arr, int left, int mid, int right){
//左邊數組檢測的下標
int leftIndex = left;
//右邊數組檢測的下標
int rightIndex = mid + 1;
//歸併後的數組的下標
int mergeIndex = left;
//歸併排序裝歸併結果的數組
int [] mergeArray = new int[arr.length];
//當左數組和右數組都未到最右邊
while(leftIndex <= mid && rightIndex <= right){
//如果左數組的元素小於等於右數組的元素
if(arr[leftIndex] <= arr[rightIndex]) {
//將左數組的元素放入歸併後的數組,左數組index + 1
mergeArray[mergeIndex++] = arr[leftIndex++];
//如果左數組元素大於右數組元素
} else {
//將右數組的元素放入歸併後的數組,右數組index + 1
mergeArray[mergeIndex++] = arr[rightIndex++];
}
}//本while循環結束,左右數組至少有一個遍歷結束
//如果左數組沒有遍歷結束
while(leftIndex <= mid){
//將左數組剩下的元素依次放入歸併後的數組
mergeArray[mergeIndex++] = arr[leftIndex++];
}
//如果右數組沒有遍歷結束
while(rightIndex <= right){
//將右數組剩下的元素依次放入歸併後的數組
mergeArray[mergeIndex++] = arr[rightIndex++];
}
//將歸併後的有序數組,複製代替原來的數組
for (int i = left; i <= right; i++){
arr[i] = mergeArray[i];
}
}
/**
* 歸併排序(MergeSort)的驅動程序
* @param arr 待排序的數組
*/
public static void mergeSort(int[] arr){
//歸併排序的左邊界
int left = 0;
//歸併排序的右邊界
int right = arr.length - 1;
//調用歸併排序的方法
mergeSort(arr, left, right);
}
/**
* 驗證歸併排序算法
* @param args
*/
public static void main(String[] args) {
//待排序數組
int[] arr = new int[30];
//隨機數類
Random random = new Random();
//隨機生成排序數組(100以內的整數)
for (int i = 0; i < arr.length; i++) {
arr[i] = random.nextInt(100);
}
//打印待排序數組
System.out.println("歸併排序前:" + Arrays.toString(arr));
//進行歸併排序(調用驅動程序,就是隻有一個參數的mergeSort()方法)
mergeSort(arr);
//打印歸併排序後的數組
System.out.println("歸併排序後:" +Arrays.toString(arr));
}
}
運行 MergeSort 類的main方法,歸併排序算法測試通過:
歸併排序前:[33, 39, 17, 51, 8, 28, 92, 93, 30, 52, 25, 45, 36, 52, 4, 89, 67, 23, 42, 29, 59, 50, 18, 82, 37, 59, 32, 48, 12, 51]
歸併排序後:[4, 8, 12, 17, 18, 23, 25, 28, 29, 30, 32, 33, 36, 37, 39, 42, 45, 48, 50, 51, 51, 52, 52, 59, 59, 67, 82, 89, 92, 93]