归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
看到一篇博客讲的蛮好的,动态图很生动,下面是链接:
http://blog.csdn.net/wu_lai_314/article/details/8450933
博主同时还在另外一篇博文中介绍了一种改进算法,不过代码虽然能得到正确结果,但是由于程序逻辑不对,实际排序是通过插入排序法进行排序的,其归并排序算是绕了一圈没有解决问题。其链接如下:
http://blog.csdn.net/wu_lai_314/article/details/8452526
这里是我进行修改后的代码:
#define M 16 #include<iostream> #include <time.h> #include<iomanip> using namespace std; void insertSort(int *a, int left, int right){ int tmp; int i, j; for (i = left + 1; i <= right; i++){//外层循环是从第二个元素开始的 if (a[i]<a[i - 1]){ tmp = a[i]; j = i - 1; do{ a[j + 1] = a[j--]; } while (j >= left && tmp < a[j]); a[j + 1] = tmp; } } } void improvedMerge(int *a, int left, int mid, int right){ int s1 = left;//s1,s2 是检测指针,t是存放指针 int s2 = right; int t = left, k; int *b = new int[right]; for (k = left; k <= mid; k++)//正向复制 b[k] = a[k]; for (k = mid + 1; k <= right; k++)//反向复制 b[right + mid + 1 - k] = a[k]; while (t <= right){//归并过程 if (b[s1] <= b[s2]) a[t++] = b[s1++]; else a[t++] = b[s2--]; } } void doSort(int *a, int left, int right){ if (left >= right) return; if (right - left + 1 < M) { insertSort(a, left, right);//序列长度小于M时候,进行插入排序,再跳出循环 return; } int mid = (left + right) / 2;//从中间划分两个子序列 doSort(a, left, mid);//从左侧子序列进行递归排序 doSort(a, mid + 1, right);//从右侧子序列进行递归排序 improvedMerge(a, left, mid, right);//合并 } void main(){ int a[100]; srand((unsigned int)time(NULL)); for (int i = 0; i<100; i++) a[i] = rand(); doSort(a, 0, 99); for (int i = 0; i<100; i++){ if (i % 7 == 0 && i != 0) cout << endl; cout << setw(10) << a[i] << " "; } cout << endl; getchar(); }