常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图归纳:算法
归并排序(英语: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