二路归并排序:
基本思想:将两个有序表合并成一个有序表。(将下列两个已排序的顺序表合并成一个已排序表。顺序比较两 者的相应元素,小者移入另一表中,反复如此,直至其中任一表都移入另 一表为止。)
二路归并排序的基本思想是将两个有序表合并成一个有序表。
给定排序码46,55,13,42,94,05,17,70,二路归并排序过程为:
//将两个有序序列合并
void Merge(int* arr, int* tmp, int start, int mid, int end)
{
int i = start; //序列A的起始位置
int j = mid +1;//序列B的起始位置
int k = start;//新序列的起始位置
//将arr[]平分为两个有序序列,序列1(start~mid)、序列2(mid+1 ~end)
while(i < mid + 1 && j < end + 1)
{
//将两个序列较小元素放入新序列中
if(arr[i] <= arr[j])
{
tmp[k++] = arr[i++];
}
else
{
tmp[k++] = arr[j++];
}
}
//序列A还有元素,全部放到新序列
while(i < mid + 1)
{
tmp[k++] = arr[i++];
}
//序列B还有元素,全部放到新序列
while(j < end +1)
{
tmp[k++] = arr[j++];
}
//将有序新序列复制到原序列
for(int i = 0; i < end; i++)
{
arr[i] = tmp[i];
}
}
//将一个待排序列划分,直到序列只有一个元素,进行合并
void MergePartition(int* arr, int* tmp, int start, int end)
{
int mid = (end - start) / 2 + start;
if(start < end)
{
MergePartition(arr, tmp, start, mid);
MergePartition(arr, tmp, mid + 1, end);
Merge(arr, tmp, start, mid, end);
}
}
void MergeSort(int* arr, int len)
{
int* tmp = (int*)malloc(len * sizeof(int));
MergePartition(arr, tmp, 0, len - 1);
free(tmp);
}
2-路归并排序的时间复杂度为O(nlog2n)。
用二路归并排序时,需要利用与待排序数组相同的辅助数组作临时单元,故该排序方法的空间复杂度为O(n)。
2-路归并排序是一种稳定的排序方法。