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


    动图演示

    归并排序(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 }
  • 相关阅读:
    react脚手架和JSX
    promise
    防抖和节流
    call/apply/bind 用法
    js this指向
    vue单页面应用刷新网页后vuex的state数据丢失的解决方案
    Echarts基础
    继承
    原型链
    vue项目中使用生成动态二维码
  • 原文地址:https://www.cnblogs.com/wangchaoguo-li/p/14205742.html
Copyright © 2020-2023  润新知