JavaScript算法 ,Python算法,Go算法,java算法,系列之歸併排序

常見的內部排序算法有:插入排序、希爾排序、選擇排序、冒泡排序、歸併排序、快速排序、堆排序、基數排序等。用一張圖歸納:算法

clipboard.png

歸併排序(英語:Merge sort,或mergesort),是建立在歸併操做上的一種有效的排序算法,效率爲O(n log n)。1945年由約翰·馮·諾伊曼首次提出。該算法是採用分治法(Divide and Conquer)的一個很是典型的應用,且各層分治遞歸能夠同時進行。數組

clipboard.png

做爲一種典型的分而治之思想的算法應用,歸併排序的實現由兩種方法:
自上而下的遞歸(全部遞歸的方法均可以用迭代重寫,因此就有了第 2 種方法);
自下而上的迭代;
在《數據結構與算法 JavaScript 描述》中,做者給出了自下而上的迭代方法。可是對於遞歸法,做者卻認爲:
However, it is not possible to do so in JavaScript, as the recursion goes too deep for the language to handle.
然而,在 JavaScript 中這種方式不太可行,由於這個算法的遞歸深度對它來說太深了。
說實話,我不太理解這句話。意思是 JavaScript 編譯器內存過小,遞歸太深容易形成內存溢出嗎?還望有大神可以指教。
和選擇排序同樣,歸併排序的性能不受輸入數據的影響,但表現比選擇排序好的多,由於始終都是 O(nlogn) 的時間複雜度。代價是須要額外的內存空間。數據結構


  1. 算法步驟app

  2. 申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列;ide

  3. 設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置;性能

  4. 比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置;spa

  5. 重複步驟 3 直到某一指針達到序列尾;指針

  6. 將另外一序列剩下的全部元素直接複製到合併序列尾。code

  7. 動圖演示排序

clipboard.png

  1. JavaScript 代碼實現

function mergeSort(arr) {  
    var len = arr.length;
    if(len < 2) {
        return arr;
    }
    var middle = Math.floor(len / 2),
        left = arr.slice(0, middle),
        right = arr.slice(middle);
    return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right){
    var result = [];

    while (left.length && right.length) {
        if (left[0] <= right[0]) {
            result.push(left.shift());
        } else {
            result.push(right.shift());
        }
    }

    while (left.length)
        result.push(left.shift());

    while (right.length)
        result.push(right.shift());

    return result;
}
  1. Python 代碼實現

def mergeSort(arr):
    import math
    if(len(arr)<2):
        return arr
    middle = math.floor(len(arr)/2)
    left, right = arr[0:middle], arr[middle:]
    return merge(mergeSort(left), mergeSort(right))

def merge(left,right):
    result = []
    while left and right:
        if left[0] <= right[0]:
            result.append(left.pop(0));
        else:
            result.append(right.pop(0));
    while left:
        result.append(left.pop(0));
    while right:
        result.append(right.pop(0));
    return result
  1. Go 代碼實現

func mergeSort(arr []int) []int {
        length := len(arr)
        if length < 2 {
                return arr
        }
        middle := length / 2
        left := arr[0:middle]
        right := arr[middle:]
        return merge(mergeSort(left), mergeSort(right))
}

func merge(left []int, right []int) []int {
        var result []int
        for len(left) != 0 && len(right) != 0 {
                if left[0] <= right[0] {
                        result = append(result, left[0])
                        left = left[1:]
                } else {
                        result = append(result, right[0])
                        right = right[1:]
                }
        }

        for len(left) != 0 {
                result = append(result, left[0])
                left = left[1:]
        }

        for len(right) != 0 {
                result = append(result, right[0])
                right = right[1:]
        }

        return result
}

7 Java 實現

public static int[] sort(int[] nums, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
        
            sort(nums, low, mid);
       
            sort(nums, mid + 1, high);

            merge(nums, low, mid, high);
        }
        return nums;
    }

    /**
     * 將數組中low到high位置的數進行排序
     * nums 待排序數組
     * low 待排的開始位置
     *  mid 待排中間位置
     *  high 待排結束位置
     */
    public static void merge(int[] nums, int low, int mid, int high) {
        int[] temp = new int[high - low + 1];
        int i = low;
        int j = mid + 1;
        int k = 0;

        while (i <= mid && j <= high) {
            if (nums[i] < nums[j]) {
                temp[k++] = nums[i++];
            } else {
                temp[k++] = nums[j++];
            }
        }

        while (i <= mid) {
            temp[k++] = nums[i++];
        }

        while (j <= high) {
            temp[k++] = nums[j++];
        }

      
        for (int k2 = 0; k2 < temp.length; k2++) {
            nums[k2 + low] = temp[k2];
        }
    }

但願能夠一塊兒交流技術,有興趣能夠加qq邀請入羣:525331804 全棧技術開發qq羣:581993430

相關文章
相關標籤/搜索