归并排序
是一种稳定的排序方法,时间复杂度是 O(nlog2 N)。
基本思想:
将若干有序序列逐步归并,最终归并为一个有序序列。
代码:
void Merge(int r[],int r1[],int s,int m,int t)//一次归并算法
{
int i, j, k;
i = s;
j = m + 1;
k = s;
while (i <= m && j <= t)
{
if (r[i] <= r[j])
{
r1[k++] = r[i++]; // 取 r[i] 和 r[j] 中的较小者放入 r1[k]
}
else
{
r1[k++] = r[j++];
}
}
if (i <= m)
{
while (i <= m) //若第一个子序列没处理完,则进行收尾处理
{
r1[k++] = r[i++];
}
}
else
{
while (j <= t) //若第二个子序列没处理完,则进行收尾处理
{
r1[k++] = r[j++];
}
}
}
void MergePass(int r[],int r1[],int n,int h)//一趟归并算法
{
int i, k;
i = 1; //从下标1开始存放待排序列
while (i <= n - 2 * h + 1) //待归并记录至少有两个长度为h的子序列
{
Merge(r, r1, i, i + h - 1, i + 2 * h - 1);
i += 2 * h;
}
if (i < n - h + 1) //待归并序列中有一个长度小于h
{
Merge(r, r1, i, i + h - 1, n);
}
else //待归并序列中只剩一个子序列
{
for (k = i; k <= n;k++)
{
r1[k] = r[k];
}
}
}
非递归实现:
void MergeSort1(int r[],int r1[],int n)
{
int h = 1;
while (h < n)
{
MergePass(r, r1, n, h);
h = 2 * h;
MergePass(r1, r, n, h);
h = 2 * h;
}
}
递归实现:
void MergeSort2(int r[],int r1[],int s,int t)
{
int m;
if (s == t)
{
r1[s] = r[s];
}
else
{
m = (s + t) / 2;
MergeSort2(r, r1, s, m);
MergeSort2(r, r1, m + 1, t);
Merge(r1, r, s, m, t);
}
}