排序之歸併排序

  • 排序是將一串數據按照其某個或者某些關鍵字的大小進行遞增或遞減排列的操做我,一般指的排序是升序,排序方式是原地排序
  • 下面介紹下歸併排序

歸併排序

  • 原理:
    • 創建在歸併操做上的一種有效的排序算法
    • 將已有序的子序列合併,獲得徹底有序的序列
    • 即先使每一個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併
  • 歸併排序是一個穩定的排序

實現方式

  • 合併:是歸併排序的核心操做
  • 代碼以下:算法

    private void merge(int[] array, int left, int mid, int right) {
                int i = left;
                int j = mid;
                int length = right - left;
                int[] extra = new int[length];
                int k = 0;
    
                while(i < mid && j < right) {
                        if(array[i] <= array[j]) {
                                extra[k++] = array[i++];
                        } else {
                                extra[k++] = array[j++];
                        }
                }
    
                while (i < mid) {
                        extra[k++] = array[i++];
                }
                while (j < right) {
                        extra[k++] = array[j++];
                }
    
                // 從 extra 搬移回 array
                for (int t = 0; t < length; t++) {
                // 須要搬移回原位置,從 low 開始
                        array[left + t] = extra[t];
                }
        }
  • 遞歸實現操做:ide

    public void mergeSort(int[] array) {
        mergeSortInternal(array, 0, array.length);
    }
    
    private void mergeSortInternal(int[] array, int left, int right) {
        if(left >= right - 1)
            return;
    
        int mid = (left + right) >>> 1;
        mergeSortInternal(array, left, mid);
        mergeSortInternal(array, mid, right);
    
        merge(array, left, mid, right);
    }
  • 非遞歸實現操做
    public void mergeSort(int[] array) {
                for (int i = 1; i < array.length; i = i * 2) {
                        for (int j = 0; j < array.length; j = j + 2 * i) {
                                int low = j;
                                int mid = j + i;
                                if (mid >= array.length) {
                                        continue;
                                }
                                int high = mid + i;
                                if (high > array.length) {
                                        high = array.length;
                                }
                                merge(array, low, mid, high);
                        }
                }
        }

性能分析

  • 時間複雜度:O(N * log(N))
  • 空間複雜度:O(N)
  • 穩定性:穩定
相關文章
相關標籤/搜索