(二路)归并排序指的是将两个顺序序列合并成一个顺序序列的方法。它是采用分治法的一个典型应用。
如 设有数列初始状态为:6,202,100,301,38,8,1
第一次归并后:{6,202},{100,301},{8,38},{1}
第二次归并后:{6,100,202,301},{1,8,38}
第三次归并后:{1,6,8,38,100,202,301}
归并排序时间复杂度为o(nlogn),空间复杂度为o(n),是一种稳定的排序方法。
完整代码如下:
#include<iostream>
#define N 20
void mergeSort(int* arr, int s,int t);
void merge(int* arr, int s, int m,int t);
int temp[N];//备用数组temp
int main()
{
int a[N] = { 3, 2, 4, 6, 7, 5, 18, 9, 0, 1,
16, 8, 20, 33, 28, 64, 19, 31, 30, 25 };
for (int i = 0; i <N; i++)
{
std::cout << a[i] << " ";
}
std::cout << '\n';
mergeSort(a,0,N-1);
for (int i = 0; i <N; i++)
{
std::cout << a[i] << " ";
}
std::cout << '\n';
return 0;
}
void mergeSort(int* arr, int s, int t)
{
if (s < t)
{
int m = (s + t) / 2;
mergeSort(arr, s, m);
mergeSort(arr, m + 1, t);
merge(arr, s, m, t);
}
}
void merge(int* arr, int s, int m, int t)
{
int i, j;//i表示在temp中的下标,下面初始化为0;
int start = s;//start保留arr数组中归并的起始位置 s,方便后面copy;
for (j = m + 1,i=0; j <= t&&s<= m;++i) s为前半部分有序数组起始下标,j为后半部分;
{
if (arr[s] <= arr[j])//保证排序的稳定性(不能写成arr[s]<arr[j])
temp[i] = arr[s++];
else
temp[i] = arr[j++];
}
while (s <= m)
temp[i++] = arr[s++];
while (j<=t)
temp[i++] = arr[j++];
i = 0;
while (start <= t)//copy排好序的数。
arr[start++] = temp[i++];
}