合并排序是用分治策略实现对n 个元素进行排序的算法。其基本思想是,将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集合合并成所要求的排好序的集合。
其递归描述如下:
#include <iostream>
#define N 8
typedef int Type;
using namespace::std;
Type *b = new Type[N];
void MergeSort(Type a[], int left, int right);
void Merge(Type a[], Type b[], int left, int i, int right );
void MergeSort(Type a[], int left, int right)
{
if(left < right)
{
int i = (left + right) / 2;
MergeSort(a, left, i);
MergeSort(a, i+1, right);
Merge(a, b, left, i, right); //Merge to array of 'b'
}
}
void Merge(Type a[], Type b[], int left, int i, int right )
{
int x = left, y = i+1, k = left;
while((x <= i) && (y <= right))
{
if(a[x] < a[y]) b[k++] = a[x++];
else b[k++] = a[y++];
}
while(x <= i) b[k++] = a[x++];
while(y <= right) b[k++] = a[y++];
for(int i = left; i < k; i++)
a[i] = b[i];
}
int main()
{
Type a[N] = {4,8,3,7,1,5,6,2};
MergeSort(a, 0, 7);
for(int i = 0; i < N; i++)
cout << a[i] << ',';
cout << endl;
return 1;
}
#include <iostream>
typedef int Type;
using namespace::std;
void Merge(Type c[], Type d[], int l, int m, int r)
{
int i = l, j = m+1, k = l;
while((i <= m) && (j <= r))
{
if(c[i] <= c[j]) d[k++] = c[i++];
else d[k++] = c[j++];
}
if(i > m) for(int q = j; q <= r; q++) d[k++] = c[q];
else for(int q = i; q <= m; q++) d[k++] = c[q];
}
void MergePass(Type x[], Type y[], int s, int n)
{
int i = 0;
while( i <= n - 2 * s)
{
Merge(x, y, i, i+s-1, i+2*s-1);
i = i+2 * s;
}
if(i + s < n) Merge(x, y, i, i+s-1, n-1);
else for(int j = i; j <= n-1; j++) y[j] = x[j];
}
void MergeSort(Type a[], int n)
{
Type *b = new Type[n];
int s = 1;
int i = 0;
while(s < n)
{
MergePass(a,b,s,n); //合并到数组b
s += s;
MergePass(b,a,s,n); // 合并到数组a
s += s;
}
}
int main()
{
Type num[] = {8,4,7,3,1,5,6,2};
MergeSort(num, 8);
for(int j = 0; j < 8; j++)
cout << num[j];
int i;
cin >> i;
return 1;
}
自然合并排序如下:
#include <iostream>
#define N 8
typedef int Type ;
using namespace::std;
void MergeSort_Natural(Type a[], int n);
int Scan(Type a[], Type b[], int n);
void Merge(Type a[], Type b[], int left , int mid, int right);
//自然归并排序
void MergeSort_Natural(Type a[], int n)
{
Type *b = new Type[N];
while(1)
{
if(Scan(a,b,n) == 0) break;
if(Scan(b,a,n) == 0) break;
}
}
/* 线性扫描数列,如果存在逆序的情况就进行合并排序
否则返回一个为零的中间值mid
*/
int Scan(Type a[], Type b[], int n)
{
int left = 0, mid = 0, right = n-1;
for(int i = 0; i < n-1; i++)
{
// 判断有没有逆序的情况出现
if(a[i] > a[i+1]){
// 先设置中间值,后设置右值
if(mid == 0) mid = i;
else {
right = i;
Merge(a, b, left , mid, right);
left = right+1;
mid = 0;
right = n-1;
}
}
}
// 当最后一个组为最后一个数的极端情况
if((mid !=0) && (right != 0))
Merge(a, b, left , mid, right);
return mid;
}
void Merge(Type a[], Type b[], int left , int mid, int right)
{
int i = left, j = mid+1, k = left;
while((i <= mid) && (j <= right))
{
if(a[i] < a[j]) b[k++] = a[i++];
else b[k++] = a[j++];
}
while(i <= mid) b[k++] = a[i++];
while(j <= right) b[k++] = a[j++];
}
int main()
{
Type a[N] = {4,8,3,7,1,5,6,2};
MergeSort_Natural(a, 8);
for(int i = 0; i < N; i++)
cout << a[i] << ',';
cout << endl;
// int i;
// cin >> i;
return 1;
}
合并排序的一个弊端就是额外需要存储器的空间配置,在实际上的实现上,会极度影响速度和高速缓存的性能!