归并排序的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到int(n/2)个长度为2或1的有序子序列;再两两归并,……,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序。
void MergeSort(SqList *L)
{
MSort(L->r, L->r, 1, L->length);
}
void MSort(int SR[], int TR1[], int s, int t)
{
int m;
int TR2[MAXSIZE + 1];
if (s == t)
TR1[s] = SR[s];
else
{
m = (s + t) / 2;
MSort(SR, TR2, s, m);
MSort(SR, TR2, m+1, t);
Merge(TR2, TR1, s, m, t);
}
}
void Merge(int SR[], int TR[], int i, int m, int n)
{
int j, k, l;
for (j = m + 1, k = i; i <= m && j <= n; k++)
{
if (SR[i] < SR[j])
TR[k] = SR[i++];
else
TR[k] = SR[j++];
}
if (i <= m)
{
for (l = 0; l <= m - i; l++)
TR[k + l] = SR[i + l];
}
if (j <= n)
{
for (l = 0; l <= n - j; l++)
TR[k + l] = SR[j + l];
}
}
时间复杂度是O(nlogn),空间复杂度是O(n+nlogn)。
非递归实现归并排序:
void MergeSort2(SqList *L)
{
int k = 1;
int *TR = (int *)malloc(L->length * sizeof(int));
while (k < length)
{
MergePass(L->r, TR, k, L->length);
k = k * 2;
MergePass(TR, L->r, k, L->length);
k = k * 2;
}
}
void MergePass(int SR[], int TR[], int s, int n)
{
int i = 1;
int j;
while (i <= n - 2*s + 1)
{
Merge(SR, TR, i, i + s - 1, i + 2*s - 1);
i += 2 * s;
}
if (i < n - s + 1)
Merge(SR, TR, i, i + s - 1, n);
else
for (j = i; j <= n; j++)
TR[j] = SR[j];
}
空间复杂度为O(n)。应该说,使用归并排序时,尽量考虑用非递归方法。