“归并”一词的中文含义就是合并、并入的意思,而在数据结构中的定义就是将两个或两个以上的有序表合成一个新的有序表。
归并排序(Merging Sort)就是利用归并的思想实现的排序方法。它的原理是假设序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度都是1,然后两两合并,得到[n/2]([ ]表示不小于x的最小整数)个长度为2或1的有序子序列;再两两归并,......,如此重复,直至一个长度为n的有序序列为止。这种排序方法称为2路归并排序。
第一段程序是第二次理解(特别是非递归版本)
#include<iostream> #define MAXSIZE 50 using namespace std; void Merge(int*SR, int*TR, int a, int b, int c) { int index1 = a; int index2 = b + 1; int i; for (i = a; index1 <= b&&index2 <= c; i++) if (SR[index1] < SR[index2]) TR[i] = SR[index1++]; else TR[i] = SR[index2++]; if (index1 <= b) for (int k = 0; k <= b - index1; k++) TR[i + k] = SR[index1+k]; if (index2 <= c) for (int k = 0; k <= c - index2; k++) TR[i + k] = SR[index2 + k]; } //递归 void MSort(int*SR, int*TR1,int start, int end) { int TR2[MAXSIZE+1]; if (start == end) TR1[start] = SR[start]; else { int k = (start + end) / 2; MSort(SR, TR2, start, k); MSort(SR, TR2, k + 1, end); Merge(TR2, TR1, start, k, end); } } void MergeSort(int*SR, int*TR, int length) { MSort(SR, TR,1, length); } /*非递归 void MergePass(int*SR, int*TR, int k, int n) { int i = 1; while (i <= n - 2 * k + 1) { Merge(SR,TR,i,i+k-1,i+2*k-1); i = i + 2 * k; } if (i < n - k + 1) Merge(SR,TR,i,i+k-1,n); else for (int j = i; j <= n; j++) TR[j] = SR[j]; } void MergeSort2(int*SR, int length) { int k = 1; int*TR = (int*)malloc(length*sizeof(int)); while (k < length) { MergePass(SR,TR,k,length); k = k * 2; MergePass(TR, SR, k, length); k = k * 2; } } */ int main() { int a[MAXSIZE+1]; int n; cin >> n; for (int i =1; i <= n; i++) cin >> a[i]; MergeSort(a,a,n); //MergeSort2(a,n); } #include<iostream> #include<vector> using namespace std; #define MAXSIZE 20 void Merge(int *SR, int *TR,int start,int m,int end) { int j, k, l; for (j = m + 1, k = start; start <= m&&j <= end; k++) //将SR中记录由小到大归并入TR { if (SR[start] < SR[j]) TR[k] = SR[start++]; else { TR[k] = SR[j++]; //cout << TR[k]; } } if (start <= m) { for (int l = 0; l <= m - start; l++) { TR[k + l] = SR[start + l]; //将剩余的SR[start..m]复制到TR //cout << TR[k]; } } if (j <= end) { for (int l = 0; l <=end-j; l++) TR[k+l] = SR[j+l]; //将剩余的SR[j..end]复制到TR } } /* 归并排序递归版 void MSort(int *SR, int *TR1,int start,int end) { int m; int TR2[MAXSIZE+1]; if (start == end) TR1[start]= SR[start]; else { m = (start + end) / 2; //将SR[s...t]平分为SR[s...m]和SR[m+1...t] MSort(SR, TR2, start, m); //递归将SR[s...m]归并为有序的TR2[s...m] MSort(SR, TR2, m+1, end); //递归将SR[m+1...t]归并为有序TR2[m+1...t] Merge(TR2,TR1,start,m,end); //将TR2[s..m]和TR2[m+1..t]归并到TR1[S...R] } } void MergeSort(int *a,int length) { //cout << a[0] << a[2] << a[5] << endl; MSort(a,a, 0, length-1); } */ //归并排序非递归版 void MergePass(int *SR, int *TR, int start,int end) { int i = 1; int j; while (i <= end - 2 * start + 1) { Merge(SR,TR,i,i+start-1,i+2*start-1); //两两归并 i = i + 2 * start; } if (i < end - start + 1) //归并最后两个序列 Merge(SR, TR, i, i + start - 1, end); else for (j = i; j <= end; j++) //若最后只剩下单个子序列 TR[j] = SR[j]; } void MergeSort2(int *a,int length) { int *TR = (int *)malloc(length * sizeof(int)); //申请额外空间 //int TR[MAXSIZE + 1]; int k = 1; while (k < length) { MergePass(a, TR, k, length); k = 2 * k; //子序列长度加倍 MergePass(TR,a, k, length); k = 2 * k; //子序列长度加倍 } } void main() { int input[MAXSIZE+1]; int n; cin >> n; for (int i = 1; i <=n; i++) { cin >> input[i]; } MergeSort2(input,n); for (int i = 1;i<=n; i++) cout << input[i] << " "; }