Merge sort algorithm thought personal understanding

  • 1. Principle: assume that the initial data has n to be sorted, the n data may be viewed as an independent sequence of n, the length of each sub-sequence is 1, then twenty-two combined to give [n / 2] of length 1 or 2 (note that if n is odd, one more element combined with other elements can not occur) in an ordered sequence ; then combined twenty-two a is repeated until the ordered sequence to obtain a length of n So far, this method of sorting is 2-way sorting method.
    13407176-ebd6aaf88cc3a208.jpg
    .Jpg merge sort process
  • 2. recursive method to implement merge sort
    • Principle: when to implement merge sort using a recursive method, the core idea is that two ordered sequences merger, consolidation note that this is an ordered sequence, so the following two things to do, the whole process as shown below:
      • (1) from the middle of the sequence to be sorted into two, the left or right and then recursively splitting operation, independently of one another to obtain the n sequence;
      • (2) for n separate sub-sequences recursively perform a merge operation, the ordered sequence of the finally obtained.


        13407176-ce9fd065c6fc390e.jpg
        Recursive method to achieve merge sort .jpg
  • Pseudocode shown below, wherein the function Merge_Sort () function is a unified interface to facilitate the user calls; msort function () recursively to obtain first n independent sequence, and then use the Merge () function to achieve an ordered sequence merge .


    13407176-2c3abe7ff8b3d880.jpg
    Merge function .jpg

    13407176-bf656e889e90f566.jpg
    Msort function .jpg

    13407176-cb6065327dc91c31.jpg
    Merge_Sort function .jpg
  • 3. Non-recursive merge sort method implementation
    • Lack of recursion: the recursive method to achieve merge sort of code easier to understand, but recursive easy to waste space, such as recursive method to achieve the above-mentioned second step merge sort, every step of the merger must create a temporary array TmpA, this array is used to temporarily hold intermediate has been sorted sequence. Then the other intermediate row sorted sequence, then the result of a temporary array TmpA redirected back in array A. The next recursive implementation of the above combined operation until the sequence is completely sorted. However, the space complexity of the whole process is too large merge sort is O (n).
    • Solution: non-recursive method implementing merge sort, in the second step can use the following ideas, than creating a temporary array TmpA at each merge, TmpA temporary array is created only once, each time after executing the merge operations the results temporarily stored in merge array TmpA, followed by the next time merge operation, the first time the TmpA good results are redirected back merge array a, then merge operation. Space complexity of the whole process will be smaller, not every operation creates a temporary array TmpA. Angelica and the last operation is performed once, if at this time the discharge sequence has been sorted in the array A, then do not lead back again in the array A; if this time has been sorted array TmpA sequence, then the perform a back into operation, it will result in the re-array TmpA back into the array a, complete the order. Pseudo code for this process is as follows:


      13407176-14ef71a3d91bfa8c.jpg
      Non-recursive method to achieve merge sort .jpg
  • 4. merge sort code to achieve two methods as follows:
      #include <iostream>
      #include <malloc.h>
    
      using namespace std;
    
      #define N 9
      #define MAXSIZE 10
    
      typedef struct
      {
          int r[MAXSIZE + 1];
          int len;
      } Sqlist;
    
      void show(Sqlist L)
      {
          for (int i = 1; i < L.len; i++)
              cout << L.r[i] << " ";
          cout << endl;
      }
    
      // 归并操作
      void Merge(int A[], int TempA[], int L, int LeftEnd, int RightEnd)
      {                // L:左边子序列的起点;LeftEnd:左边子序列的终点
          int k, j; // k是数组tempA左边起点,j是右边子序列的的起点,RightEnd:右边子序列的终点
          for (j = LeftEnd + 1, k = L; L <= LeftEnd && j <= RightEnd; k++)
          {
              if (A[L] < A[j])
                  TempA[k] = A[L++];
              else
                  TempA[k] = A[j++];
          }
          if (L <= LeftEnd)
          {
              for (int l = 0; l <= LeftEnd - L; l++)
                  TempA[k + l] = A[L + l];
          }
          if (j <= RightEnd)
          {
              for (int r = 0; r <= RightEnd - j; r++)
                  TempA[k + r] = A[j + r];
          }
      }
      // 递归方法实现
      // 归并排序整个操作
      void Msort(int A[], int TempA[], int L, int RightEnd)
      {
          int center;
          int TempA2[MAXSIZE + 1];
          if (L == RightEnd)
              TempA[L] = A[L];
          else
          {
              center = (L + RightEnd) / 2;
              Msort(A, TempA2, L, center);
              Msort(A, TempA2, center + 1, RightEnd);
              Merge(TempA2, TempA, L, center, RightEnd);
          }
      }
    
      // 统一函数接口
      void MergeSort(Sqlist *L)
      {
          Msort(L->r, L->r, 1, L->len);
      }
    
      // 非递归方法实现
      void MergePass(int A[], int TempA[], int length, int n)
      {
          // length:当前子序列的长度  n:待排序列中的元素个数
          int i = 1;
          while (i <= n - 2 * length - 1)
          { // 子序列的个数是偶数个
              Merge(A, TempA, i, i + length - 1, i + 2 * length - 1);
              i = i + 2 * length;
          }
          if (i < n - length + 1) // 归并最后两个子序列
              Merge(A, TempA, i, i + length - 1, n);
          else
          { // 最后只剩下一个子序列
              for (int j = i; j <= n; j++)
                  TempA[j] = A[j];
          }
      }
    
      // 统一函数接口
      void MergeSort1(Sqlist *L)
      {
          int *TempA = (int *)malloc(L->len * sizeof(int));
          int length = 1; // 初始子序列的长度
      
          while (length < L->len)
          {
              MergePass(L->r, TempA, length, L->len);
              length *= 2;
              MergePass(TempA, L->r, length, L->len);
              length *= 2;
          }
      }
    
      int main()
      {
          Sqlist L;
          int d[N] = {50, 10, 90, 30, 70, 40, 80, 60, 20};
          for (int i = 0; i < N; i++)
              L.r[i + 1] = d[i];
          L.len = N;
          cout << "归并排序前(递归方法): ";
          show(L);
          cout << "归并排序后(递归方法): ";
          MergeSort(&L);
          show(L);
          cout << "-------------------------------------------------\n";
          cout << "归并排序前(非递归方法): ";
          show(L);
          cout << "归并排序后(非递归方法): ";
          MergeSort1(&L);
          show(L);
    
          return 0;
      }
    

Reproduced in: https: //www.jianshu.com/p/f8d04dc87b30

Guess you like

Origin blog.csdn.net/weixin_33859231/article/details/91194858