0Basic C# Notes 10: Merge Sort Method


Preface

To sort a large unordered array, we can divide the large array into two, then sort the two arrays separately, and then merge the two arrays into an ordered array. Since both small arrays are ordered, merging is very fast.


1. Recursive method

Divide the large array recursively until the size of the array is 1. At this time, there is only one element, then the array is in order. Then the two arrays with size 1 are merged into one with size 2. , and then merge the two ones with size 2 into 4... until all the small arrays are combined.

To facilitate understanding, I also prepared an animation:
Insert image description here

2. Code

public class MergeSort {
    
    
    // 归并排序
    public static int[] mergeSort(int[] arr, int left, int right) {
    
    
        // 如果 left == right,表示数组只有一个元素,则不用递归排序
        if (left < right) {
    
    
            // 把大的数组分隔成两个数组
            int mid = (left + right) / 2;
            // 对左半部分进行排序
            arr = mergeSort(arr, left, mid);
            // 对右半部分进行排序
            arr = mergeSort(arr, mid + 1, right);
            //进行合并
            merge(arr, left, mid, right);
        }
        return arr;
    }

    // 合并函数,把两个有序的数组合并起来
    // arr[left..mif]表示一个数组,arr[mid+1 .. right]表示一个数组
    private static void merge(int[] arr, int left, int mid, int right) {
    
    
        //先用一个临时数组把他们合并汇总起来
        int[] a = new int[right - left + 1];
        int i = left;
        int j = mid + 1;
        int k = 0;
        while (i <= mid && j <= right) {
    
    
            if (arr[i] < arr[j]) {
    
    
                a[k++] = arr[i++];
            } else {
    
    
                a[k++] = arr[j++];
            }
        }
        while(i <= mid) a[k++] = arr[i++];
        while(j <= right) a[k++] = arr[j++];
        // 把临时数组复制到原数组
        for (i = 0; i < k; i++) {
    
    
            arr[left++] = a[i];
        }
    }
}

But what if the interviewer asks you to write a non-recursive merge sort? Don’t be afraid, I also made a non-recursive merge sort. The code is as follows:

public class MergeSort {
    
    
    // 非递归式的归并排序
    public static int[] mergeSort(int[] arr) {
    
    
        int n = arr.length;
        // 子数组的大小分别为1,2,4,8...
        // 刚开始合并的数组大小是1,接着是2,接着4....
        for (int i = 1; i < n; i += i) {
    
    
            //进行数组进行划分
            int left = 0;
            int mid = left + i - 1;
            int right = mid + i;
            //进行合并,对数组大小为 i 的数组进行两两合并
            while (right < n) {
    
    
                // 合并函数和递归式的合并函数一样
                merge(arr, left, mid, right);
                left = right + 1;
                mid = left + i - 1;
                right = mid + i;
            }
            // 还有一些被遗漏的数组没合并,千万别忘了
            // 因为不可能每个字数组的大小都刚好为 i
            if (left < n && mid < n) {
    
    
                merge(arr, left, mid, n - 1);
            }
        }
        return arr;
    }
}

Summarize

Properties:
1. Time complexity: O(nlogn)
2. Space complexity: O(n)
3. Stable sorting
4. Non-in-place sorting

Guess you like

Origin blog.csdn.net/BeanGo/article/details/132210899