读周颜军; 王玉茹; 关伟洲. 数据结构 (21世纪高等教育计算机规划教材) (p. 216). 人民邮电出版社. 此书源码也是摘自此书
归并 排序( merge sort) 是 又一 类 不同 的 排序 方法。
归并 排序 的 基本 思想: 将 已 有序 的 子 文件 进行 合并, 得到 完全 有序 的 文件。
合并 时 只要 比较 各 有序 子 文件 的 第一个 记录 的 排序 码, 排序 码 最小 的 那个 记录 就是 排序 后的 第一个 记录; 取出 这个 记录, 然后 继续 比较 各个 子 文件 的 第一个 记录, 便可 找出 排序 后的 第二个 记录; 如此 继续 下去, 只要 经过 一 趟 扫描 就可以 得到 最终 的 排序 结果。
对于 排序 码 任意 排列 的 待 排序 文件 进行 归并 排序 时, 可以 把 文件 中的 n 个 记录 看成 n 个子 文件。
每个 子 文件 只 包含 一个 记录, 显然 对于 个子 文件 来说 是 有序 的。
但是, 要想 只 经过 一 趟 扫描 就 将 n 个子 文件 全部 归并 成 一个 有序 的 文件 显然 是 困难 的。
通常, 可以 采用 两两 归并 的 方法, 即 每次 将 两个 子 文件 归并 成 一个 较大 的 有序 子 文件。
第一 趟 归并 后, 得到 个 长度 为 2 的 有序 子 文件( 最后 一个 子 文件 长度 可 能为 1); 在此 基础上, 再进 行 以后 各 趟 的 归并, 每 经过 一 趟 后, 子 文件 的 个数 约 减少 一半, 而每 个子 文件 的 长度 约 增加 一倍。
如此 反复, 直到 最后 一 趟 将 两个 有序 子 文件 归并 到 一个 文件 中,这时 整个 排序 工作 就 完成 了。
上述 的 归并 过程中, 每次 都是 将 两个 子 文件 合并 成 一个 较 大的 子 文件。 这种 归并 方法 称为 二路 归并( 2- way merge) 排序。 类似 地 也可以 采用 三路 归并 排序 或 多路 归并( multi - way merge) 排序。
源码如下:
void Merge(int x[],int y[], int low, int m, int high)
{
int i,j,k,h;
i = low-1;
j = m ;
k = low-1;
cout << "low: " << low << " m: " << m << " high: " << high << endl;
while (i < m && j < high)
{
if (x[i] <= x[j])
{
//cout << "1 x[" << i << "]: " << x[i] << " -> y[" << k << "]: " << endl;
y[k++] = x[i++];
}
else
{
//cout << "2 x[" << j << "]: " << x[j] << " -> y[" << k << "]: " << endl;
y[k++] = x[j++];
}
}
if (i < m)
{
for (h = i; h < m; h++, k++)
{
//cout << "3 x[" << h << "]: " << x[h] << " -> y[" << k << "]: " << endl;
y[k] = x[h];
}
}
if (j < high)
{
for (h = j; h < high; h++, k++)
{
//cout << "4 x[" << h << "]: " << x[h] << " -> y[" << k << "]: " << endl;
y[k] = x[h];
}
}
}
void MergePass(int x[], int y[], int n, int length)
{
int i = 1, k;
while (i <= n - 2 * length +1)
{
Merge(x, y, i, i + length - 1, i + 2 * length - 1);
i = i + 2 * length;
}
if (i < n - length+1 )
{
cout << " start2 " << endl;
Merge(x, y, i, i + length - 1, n);
print(y, 15, 8);
print(x, 15, 8);
cout << " end2 " << endl;
}
else
{
cout << " start3 "<< i <<endl;
for (k = i-1; k < n; k++)
{
y[k] = x[k];
}
print(y, 15, 8);
print(x, 15, 8);
cout << " end3 " << endl;
}
}
void MergeSort(int R[], int n)
{
int R1[25 + 1];
int i=0, length = 1;
memset(R1,-1,sizeof(R1));
while (length < n) {
MergePass(R, R1, n, length);
length = 2 * length;
if (length >= n) {
for (i = 0;i < n;i++)
R[i] = R1[i];
return;
// break;
}
//print(R, 15, length);
//print(R1, 15, length);
//system("pause");
MergePass(R1, R, n, length);
length = 2 * length;
}
}
int main(void) {
//int x[12] = {8,1,3,2,6,5,9,7,8,4,0,4};
//int x[12] = { 0,0,1,1,2,3,4,5,6,7,8,9 };
//int x[23] = { 0,4,8,6,2,3,1,9,7,5,3,3,8,7,5,6,11,12,10,89,54,57,58 };
int x[23] = { 0,4,8,6,2,3,1,9,7,5,3,3,8,7,5 };
int b[25] ;
memset(b, 0x00, sizeof(b));
//mpsort(x, 12);
//mpsort2(x, 12);
//quitsort(x, 0, 11, 12);
//gb1(x, b, 0, 8, 15);
//gb2(x, b, 15, 1);
//gb3(x, 15,b);
MergeSort(x, 15);
//MergeSort(x,23);
print(x, 15, 8);
//print(x, 23, 8);
cout << endl<< "循环次数:" << gnum << endl;
system("pause");
return 0;
}