Data structure and algorithm-Graphical Merge Sort algorithm and C/C++ code implementation [Recommended collection]

1. Introduction to Merge Sort

Combining two sequence of ordinal numbers into one sequence of ordinal numbers is called "merging".
Merge Sort (Merge Sort) is to sort the sequence of numbers using the idea of ​​merging. According to the specific implementation, the merging sort includes two ways: "from top to bottom" and "from bottom to top".

  1. Merging and sorting from bottom to top: divide the sequence to be sorted into several sub-sequences of length 1, and then merge these sequence in pairs; get several ordinal sequences of length 2, and then merge these sequence in pairs; Get a number of ordinal sequence of length 4, then merge them two by two; merge them directly into one sequence. In this way, we get the sort result we want. (Refer to the picture below)

  2. Merge sorting from top to bottom: it and "bottom to top" are opposite in sorting. It basically includes 3 steps:
    ① Decomposition – divide the current interval into two, that is, find the split point mid = (low + high)/2;
    ② Solve – recursively perform two subintervals a[low…mid] and a[mid +1...high] to merge and sort. The end condition of the recursion is that the length of the subinterval is 1.
    ③ Merge – merge the two sorted sub-intervals a[low…mid] and a[mid+1…high] into an ordered interval a[low…high].

The picture below clearly reflects the difference between "from bottom to top" and "from top to bottom" merge sort.
Insert picture description here

Two, merge and sort graphic description

归并排序(从上往下)代码

/*
 * 将一个数组中的两个相邻有序区间合并成一个
 *
 * 参数说明:
 *     a -- 包含两个有序区间的数组
 *     start -- 第1个有序区间的起始地址。
 *     mid   -- 第1个有序区间的结束地址。也是第2个有序区间的起始地址。
 *     end   -- 第2个有序区间的结束地址。
 */
void merge(int a[], int start, int mid, int end)
{
    
    
    int *tmp = (int *)malloc((end-start+1)*sizeof(int));    // tmp是汇总2个有序区的临时区域
    int i = start;            // 第1个有序区的索引
    int j = mid + 1;        // 第2个有序区的索引
    int k = 0;                // 临时区域的索引

    while(i <= mid && j <= end)
    {
    
    
        if (a[i] <= a[j])
            tmp[k++] = a[i++];
        else
            tmp[k++] = a[j++];
    }

    while(i <= mid)
        tmp[k++] = a[i++];

    while(j <= end)
        tmp[k++] = a[j++];

    // 将排序后的元素,全部都整合到数组a中。
    for (i = 0; i < k; i++)
        a[start + i] = tmp[i];

    free(tmp);
}

/*
 * 归并排序(从上往下)
 *
 * 参数说明:
 *     a -- 待排序的数组
 *     start -- 数组的起始地址
 *     endi -- 数组的结束地址
 */
void merge_sort_up2down(int a[], int start, int end)
{
    
    
    if(a==NULL || start >= end)
        return ;

    int mid = (end + start)/2;
    merge_sort_up2down(a, start, mid); // 递归排序a[start...mid]
    merge_sort_up2down(a, mid+1, end); // 递归排序a[mid+1...end]

    // a[start...mid] 和 a[mid...end]是两个有序空间,
    // 将它们排序成一个有序空间a[start...end]
    merge(a, start, mid, end);
}

When sorting the array {80,30,60,40,20,10,50,70} by "merge sort from top to bottom":

  1. Consider the array {80,30,60,40,20,10,50,70} as composed of two ordered sub-arrays {80,30,60,40} and {20,10,50,70}. Just sort the two ordered subtree groups.
  2. Consider the sub-array {80,30,60,40} as composed of two ordered sub-arrays {80,30} and {60,40}.
    Consider the sub-array {20,10,50,70} as composed of two ordered sub-arrays {20,10} and {50,70}.
  3. Consider the sub-array {80,30} as composed of two ordered sub-arrays {80} and {30}.
    Consider the sub-array {60,40} as composed of two ordered sub-arrays {60} and {40}.
    Consider the sub-array {20,10} as composed of two ordered sub-arrays {20} and {10}.
    Consider the sub-array {50,70} as composed of two ordered sub-arrays {50} and {70}.

归并排序(从下往上)代码

/*
 * 对数组a做若干次合并:数组a的总长度为len,将它分为若干个长度为gap的子数组;
 *             将"每2个相邻的子数组" 进行合并排序。
 *
 * 参数说明:
 *     a -- 待排序的数组
 *     len -- 数组的长度
 *     gap -- 子数组的长度
 */
void merge_groups(int a[], int len, int gap)
{
    
    
    int i;
    int twolen = 2 * gap;    // 两个相邻的子数组的长度

    // 将"每2个相邻的子数组" 进行合并排序。
    for(i = 0; i+2*gap-1 < len; i+=(2*gap))
    {
    
    
        merge(a, i, i+gap-1, i+2*gap-1);
    }

    // 若 i+gap-1 < len-1,则剩余一个子数组没有配对。
    // 将该子数组合并到已排序的数组中。
    if ( i+gap-1 < len-1)
    {
    
    
        merge(a, i, i + gap - 1, len - 1);
    }
}

/*
 * 归并排序(从下往上)
 *
 * 参数说明:
 *     a -- 待排序的数组
 *     len -- 数组的长度
 */
void merge_sort_down2up(int a[], int len)
{
    
    
    int n;

    if (a==NULL || len<=0)
        return ;

    for(n = 1; n < len; n*=2)
        merge_groups(a, len, n);
}

The idea of ​​merging and sorting from bottom to top is just the opposite of "merging and sorting from bottom to top". As shown in the figure below:
Insert picture description here
When sorting the array {80,30,60,40,20,10,50,70} by "Merge Sort from Bottom":

  1. Consider the array {80,30,60,40,20,10,50,70} as consisting of 8 ordered sub-arrays {80},{30},{60},{40},{20},{ 10}, {50} and {70}.
  2. Combine these 8 ordered sub-sequences in pairs. Get 4 ordered subtree columns {30,80}, {40,60}, {10,20} and {50,70}.
  3. Combine these 4 ordered sub-sequences in pairs. Get 2 ordered subtree columns {30,40,60,80} and {10,20,50,70}.
  4. Combine these two ordered sub-sequences in pairs. Get 1 ordered subtree column {10,20,30,40,50,60,70,80}.

The editor recommends my own linuxC/C++ language technology exchange group: [ 1106675687 ] I have compiled some learning books and video materials that I think are better to share in the group files, and you can add them if you need them!
Insert picture description here

Third, the time complexity and stability of merge sort

The time complexity of
merge sort The time complexity of merge sort is O(N lgN).
Suppose there are N numbers in the sequence being sorted. The time complexity of traversal is O(N). How many traversals are needed?
The form of merge sort is a binary tree, and the number of times it needs to be traversed is the depth of the binary tree, and according to the complete binary tree, it can be concluded that its time complexity is O(N
lgN).

Merge sort stability
Merge sort is a stable algorithm, which satisfies the definition of stable algorithm.
Algorithm stability-suppose there is a[i]=a[j] in the sequence, if before sorting, a[i] is before a[j]; and after sorting, a[i] is still before a[j] . Then this sorting algorithm is stable!

Four, merge sort implementation

Three implementations of merge sort are given below: C, C++ and Java. The principles and output results of these three implementations are the same. Each implementation includes two forms: "top-down merge sort" and "bottom-up merge sort". Merge
sort C implementation
implementation code (merge_sort.c)

View Code


Merge Sort C++ Implementation Implementation Code (MergeSort.cpp)

View Code


Merge Sort Java Implementation Code (MergeSort.java)

 View Code

The principles and output results of the above three implementations are the same. Here is their output:

before sort:80 30 60 40 20 10 50 70 
after  sort:10 20 30 40 50 60 70 80 

Guess you like

Origin blog.csdn.net/m0_50662680/article/details/113055011