十大经典排序算法(五、归并排序)

动图演示

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

  • 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);
  • 自下而上的迭代;

和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 O(nlogn) 的时间复杂度。代价是需要额外的内存空间。

算法步骤

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;

  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置;

  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;

  4. 重复步骤 3 直到某一指针达到序列尾;

  5. 将另一序列剩下的所有元素直接复制到合并序列尾。

JavaScript

 1 function mergeSort(arr) {  // 采用自上而下的递归方法
 2     var len = arr.length;
 3     if(len < 2) {
 4         return arr;
 5     }
 6     var middle = Math.floor(len / 2),
 7         left = arr.slice(0, middle),
 8         right = arr.slice(middle);
 9     return merge(mergeSort(left), mergeSort(right));
10 }
11 
12 function merge(left, right)
13 {
14     var result = [];
15 
16     while (left.length && right.length) {
17         if (left[0] <= right[0]) {
18             result.push(left.shift());
19         } else {
20             result.push(right.shift());
21         }
22     }
23 
24     while (left.length)
25         result.push(left.shift());
26 
27     while (right.length)
28         result.push(right.shift());
29 
30     return result;
31 }

Python

 1 def mergeSort(arr):
 2     import math
 3     if(len(arr)<2):
 4         return arr
 5     middle = math.floor(len(arr)/2)
 6     left, right = arr[0:middle], arr[middle:]
 7     return merge(mergeSort(left), mergeSort(right))
 8 
 9 def merge(left,right):
10     result = []
11     while left and right:
12         if left[0] <= right[0]:
13             result.append(left.pop(0))
14         else:
15             result.append(right.pop(0));
16     while left:
17         result.append(left.pop(0))
18     while right:
19         result.append(right.pop(0));
20     return result

C语言

 1 void merge_sort_recursive(int arr[], int reg[], int start, int end) {
 2     if (start >= end)
 3         return;
 4     int len = end - start, mid = (len >> 1) + start;
 5     int start1 = start, end1 = mid;
 6     int start2 = mid + 1, end2 = end;
 7     merge_sort_recursive(arr, reg, start1, end1);
 8     merge_sort_recursive(arr, reg, start2, end2);
 9     int k = start;
10     while (start1 <= end1 && start2 <= end2)
11         reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
12     while (start1 <= end1)
13         reg[k++] = arr[start1++];
14     while (start2 <= end2)
15         reg[k++] = arr[start2++];
16     for (k = start; k <= end; k++)
17         arr[k] = reg[k];
18 }
19 
20 void merge_sort(int arr[], const int len) {
21     int reg[len];
22     merge_sort_recursive(arr, reg, 0, len - 1);
23 }

C++

 1 void Merge(vector<int> &Array, int front, int mid, int end) {
 2     vector<int> LeftSubArray(Array.begin() + front, Array.begin() + mid + 1);
 3     vector<int> RightSubArray(Array.begin() + mid + 1, Array.begin() + end + 1);
 4     int idxLeft = 0, idxRight = 0;
 5     LeftSubArray.insert(LeftSubArray.end(), numeric_limits<int>::max());
 6     RightSubArray.insert(RightSubArray.end(), numeric_limits<int>::max());
 7     // Pick min of LeftSubArray[idxLeft] and RightSubArray[idxRight], and put into Array[i]
 8     for (int i = front; i <= end; i++) {
 9         if (LeftSubArray[idxLeft] < RightSubArray[idxRight]) {
10             Array[i] = LeftSubArray[idxLeft];
11             idxLeft++;
12         } else {
13             Array[i] = RightSubArray[idxRight];
14             idxRight++;
15         }
16     }
17 }
18 
19 void MergeSort(vector<int> &Array, int front, int end) {
20     if (front >= end)
21         return;
22     int mid = (front + end) / 2;
23     MergeSort(Array, front, mid);
24     MergeSort(Array, mid + 1, end);
25     Merge(Array, front, mid, end);
26 }

 

posted @ 2020-12-29 11:49  梓涵VV  阅读(118)  评论(0编辑  收藏  举报