zoukankan      html  css  js  c++  java
  • 更高效的MergeSort--稍微优化

    0. 简介

    本文简要介绍一下比传统MergeSort更高效的算法,在原来的算法Merge基础上,少发生一半拷贝。欢迎探讨,感谢阅读。

    原文链接如下:http://loverszhaokai.com/posts/More-Efficient-MergeSort/

    1. Reference

    原文链接
    Introuction to Algorithms
    https://github.com/loverszhaokai/ALG/blob/master/src/sort.cc

    2. MergeSort

    void merge(int a[], int b[], const int left, const int middle,
               const int right) {
      int li, ri, i;
    
      li = left;
      ri = middle + 1;
      i = 0;
    
      while (li <= middle && ri <= right) {
        if (a[li] < a[ri])
          b[i++] = a[li++];
        else
          b[i++] = a[ri++];
      }
    
      while (li <= middle)
        b[i++] = a[li++];
      while (ri <= right)
        b[i++] = a[ri++];
    }
    
    void copy(int dst[], int dleft, int src[], int sleft, int sright) {
      memcpy(dst + dleft, src + sleft,
             sizeof(int) * (sright - sleft + 1));
    }
    
    void _merge_sort(int a[], int b[], const int left, const int right) {
      if (left >= right)
        return;
    
      int middle = (left + right) / 2;
    
      _merge_sort(a, b, left, middle);
      _merge_sort(a, b, middle + 1, right);
    
      merge(a, b, left, middle, right);
      copy(a, left, b, 0, right - left);
    }
    
    void merge_sort(int a[], const int size) {
      int *b = (int *)malloc(size * sizeof(int));
    
      _merge_sort(a, b, 0, size - 1);
    
      free(b);
    }
    

    3. More Efficient MergeSort

    We can save some time by copy half when merge(). In merge(), we copy from
    left to right, but in MergeKai() we can only copy from left to
    middle. The merge() has NlgN duplications which the MergeKai() has
    1/2 * NlgN duplications.

    normal merge sort

                             normal merge sort
    

    efficient merge sort

                          more efficient merge sort
    

    Just as the previous example, the efficient merge sort does not need to copy
    1, 3, 7, 8 to the assit array.

    // Merge the two list in [left, mid], and (mid, right]. Then, write
    // the result to [left, right]
    static void MergeKai(int a[], int assist[], const int left,
                         const int mid, const int right) {
      int l = left;
      int r = mid + 1;
      int assist_index = 0;
    
      // Copy [left, mid] to assit[0, mid - left]
      memcpy(assist, a + left, (mid - left + 1) * sizeof(int));
    
      while (assist_index <= mid - left && r <= right) {
        if (assist[assist_index] <= a[r]) {
          a[l++] = assist[assist_index++];
          continue;
        } else if (assist[assist_index] > a[r]) {
          a[l++] = a[r++];
        }
      }
    
      while (assist_index <= mid - left) {
        a[l++] = assist[assist_index++];
      }
    
      while (r <= right) {
        a[l++] = a[r++];
      }
    }
    
    static void MergeSortKaiImpl(int a[], int assist[], const int left,
                                 const int right) {
      if (left >= right) {
        return;
      }
      const int mid = (left + right) / 2;
    
      MergeSortKaiImpl(a, assist, left, mid);
      MergeSortKaiImpl(a, assist, mid + 1, right);
    
      MergeKai(a, assist, left, mid, right);
    }
    
    void MergeSortKai(int a[], const int size) {
      int* assist= (int *)malloc(size * sizeof(int));
    
      MergeSortKaiImpl(a, assist, 0, size - 1);
    
      free(assist);
    }
    

    4. Experiments

    source:

    https://github.com/loverszhaokai/ALG/blob/master/src/sort.cc
    https://github.com/loverszhaokai/ALG/blob/master/test/sort_test.cc

    result:

    It takes 1524.61 ms to generate arrays: 1000000 * 20
    
                Sort Function      Total Run Time          Array Size
    ---------------------------------------------------------------------
       merge_sort_iteratively            826 ms            1000000 * 20
                   merge_sort            840 ms            1000000 * 20
      MergeSortIterativelyKai            826 ms            1000000 * 20
                 MergeSortKai            809 ms            1000000 * 20
    
    It takes 15028.2 ms to generate arrays: 10000000 * 20
    
                Sort Function      Total Run Time          Array Size
    ---------------------------------------------------------------------
       merge_sort_iteratively           8717 ms           10000000 * 20
                   merge_sort           8820 ms           10000000 * 20
      MergeSortIterativelyKai           8425 ms           10000000 * 20
                 MergeSortKai           8389 ms           10000000 * 20
    
    It takes 1929.31 ms to generate arrays: 100000 * 200
    
                Sort Function      Total Run Time          Array Size
    ---------------------------------------------------------------------
       merge_sort_iteratively           1245 ms             100000 * 200
                   merge_sort           1347 ms             100000 * 200
      MergeSortIterativelyKai           1246 ms             100000 * 200
                 MergeSortKai           1275 ms             100000 * 200
    
  • 相关阅读:
    JMeter 分布式调度压测部署
    jmeter 命令行运行与生成报告
    Apache启动报错:Invalid command 'AuthType', perhaps misspelled or defined by a module not included in it
    【TestNG】TestNG使用教程详解
    这才是Tomcat内存配置的正确姿势
    Tomcat GC参数详解
    MANIFEST.MF文件详解
    CMD命令打包文件夹成jar
    常用MIME类型
    表单序列化
  • 原文地址:https://www.cnblogs.com/lovers/p/merge_sort.html
Copyright © 2011-2022 走看看