算法:用Java實現歸併排序(MergeSort)

本文我準備用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]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章