常見的內部排序算法有:插入排序、希爾排序、選擇排序、冒泡排序、歸併排序、快速排序、堆排序、基數排序等。用一張圖歸納:算法
歸併排序(英語:Merge sort,或mergesort),是建立在歸併操做上的一種有效的排序算法,效率爲O(n log n)。1945年由約翰·馮·諾伊曼首次提出。該算法是採用分治法(Divide and Conquer)的一個很是典型的應用,且各層分治遞歸能夠同時進行。數組
做爲一種典型的分而治之思想的算法應用,歸併排序的實現由兩種方法:
自上而下的遞歸(全部遞歸的方法均可以用迭代重寫,因此就有了第 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) 的時間複雜度。代價是須要額外的內存空間。數據結構
算法步驟app
申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列;ide
設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置;性能
比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置;spa
重複步驟 3 直到某一指針達到序列尾;指針
將另外一序列剩下的全部元素直接複製到合併序列尾。code
動圖演示排序
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; }
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
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