一、实现思想

  1、将数组分成一个个小序列  (当然在一开始这些小序列都是一个元素)

  2、将相邻两个小序列合并起来(当然在合并的时候排好序)

 

二、实现图例

  1、递归实现

 

 

  2、非递归实现(循环实现)

 

 

三、代码实现

(递归和非递归地合并代码都是一样的,即merge函数都是一样)

  1、递归代码实现

 1 #include <stdio.h>
 2 int data[] = {8, 3, 2, 6, 7, 1, 5, 4};
 3 int length = 8;
 4 //将两个序列合并
 5 void merge(int first1, int last1, int last2)
 6 {
 7     int *temp = new int[length]; //数组temp作为合并的辅助空间,注意这个数组和原来的数组是一样大小的,为了方便
 8     int i = first1;              //左序列第一个元素下标
 9     int j = last1 + 1;           //右序列第一个元素下标
10     int k = first1;              //左序列第一个元素下标,用于记录合并后的初始位置(将temp复制到data上)
11     while (i <= last1 && j <= last2)
12     {
13         if (data[i] <= data[j])
14             temp[k++] = data[i++]; //升序排序,将小的放前面。如要修改,改变一下符号即可。
15         else
16             temp[k++] = data[j++];
17     }
18     while (i <= last1)         //做一些收尾工作,比如只剩下一边有几个(当然了,这几个必定是有序的了)
19         temp[k++] = data[i++]; //注意这里的++也很有必要,因为有可能一边的序列有好几个剩下的
20     while (j <= last2)
21         temp[k++] = data[j++];
22     for (i = first1; i <= last2; i++)
23         data[i] = temp[i];
24     delete[] temp;
25 }
26 //MergeSort和merge接收的都是数组的下标
27 void MergeSort(int first, int last)
28 {
29     if (first == last)
30         return;
31     else
32     {
33         int mid = (first + last) / 2;
34         MergeSort(first, mid);
35         MergeSort(mid + 1, last);
36         merge(first, mid, last);
37     }
38 }
39 int main(void)
40 {
41     int last = 7;
42     for (int i = 0; i < last + 1; i++)
43         printf("%d  ", data[i]);
44     printf("\n");
45     MergeSort(0, last);
46     for (int i = 0; i < last + 1; i++)
47         printf("%d  ", data[i]);
48     return 0;
49 }
/* 
输出
————————————————————————————————————
8  3  2  6  7  1  5  4  
1  2  3  4  5  6  7  8  
————————————————————————————————————
 */

  

 

   二、非递归实现(循环实现)

 1 #include <stdio.h>
 2 int data[] = {8, 3, 2, 6, 7, 1, 5, 4};
 3 int length = 8;
 4 //将两个序列合并
 5 void merge(int first1, int last1, int last2)
 6 {
 7     int *temp = new int[length]; //数组temp作为合并的辅助空间,注意这个数组和原来的数组是一样大小的,为了方便
 8     int i = first1;              //左序列第一个元素下标
 9     int j = last1 + 1;           //右序列第一个元素下标
10     int k = first1;              //左序列第一个元素下标,用于记录合并后的初始位置(将temp复制到data上)
11     while (i <= last1 && j <= last2)
12     {
13         if (data[i] <= data[j])
14             temp[k++] = data[i++]; //升序排序,将小的放前面。如要修改,改变一下符号即可。
15         else
16             temp[k++] = data[j++];
17     }
18     while (i <= last1)         //做一些收尾工作,比如只剩下一边有几个(当然了,这几个必定是有序的了)
19         temp[k++] = data[i++]; //注意这里的++也很有必要,因为有可能一边的序列有好几个剩下的
20     while (j <= last2)
21         temp[k++] = data[j++];
22     for (i = first1; i <= last2; i++)
23         data[i] = temp[i];
24     delete[] temp;
25 }
26 //MergePass和merge接收的都是数组的下标
27 void MergePass(int h)
28 {
29     int i = 0;
30     while (i + 2 * h <= length)
31     {
32         merge(i, i + h - 1, i + 2 * h - 1);
33         i = i + 2 * h;
34     }
35     if (i + h < length) //如果还有一块长度是h,另一块长度<h,则进行下面这种合并(主要是限制一下范围)
36         merge(i, i + h - 1, length - 1);
37 }
38 int main(void)
39 {
40     int last = 7;
41     for (int i = 0; i < last + 1; i++)
42         printf("%d  ", data[i]);
43     printf("\n");
44     int h = 1;
45     while (h < length)
46     {
47         MergePass(h);
48         h = 2 * h;
49     }
50     for (int i = 0; i < last + 1; i++)
51         printf("%d  ", data[i]);
52     return 0;
53 }
/* 
输出
————————————————————————————————————
8  3  2  6  7  1  5  4  
1  2  3  4  5  6  7  8  
————————————————————————————————————
 */

 

四、总结

  排序除了要了解这个大致的框架外,如果想要实现,还需要明确一下用什么来判断结束,也就是各种各样的条件

 

posted on 2020-08-06 00:49  Coderon  阅读(563)  评论(0编辑  收藏  举报