一、实现思想
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
————————————————————————————————————
*/
四、总结
排序除了要了解这个大致的框架外,如果想要实现,还需要明确一下用什么来判断结束,也就是各种各样的条件