归并排序
利用分治法的思想,归并排序将待排序的元素序列分成两个长度相等的子序列,为每个子序列排序,然后再将他们合并成一个序列。
归并排序不依赖待排序元素的序列的初始排列,这样就避免了快排的最差情况。
在执行归并算法时,先将划分的子序列复制到辅助数组中,然后将子序列按顺序存到原数组中。
这是一个稳定的排序算法,时间复杂度为O(nlog2^n)。
代码实现
首先将序列进行递归划分成最小子序列,然后进行归并
// 对序列进行划分
void doSort(int array[], int temp[], int left, int right)
{
int mid = 0; // 对序列进行划分的中间值
if (left >= right)
return;
mid = left + (right - left) / 2;
doSort(array, temp, left, mid);
doSort(array, temp, mid+1, right);
Merge(array, temp, left, mid, right);
}
归并的具体实现
// 进行归并
void Merge(int array[], int temp[], int left, int mid, int right)
{
int s1 = left;
int s2 = right;
int t = left;
int i = 0; // 拷贝序列时的下标
// left-mid
for (i = 0; i <= mid; i++)
{
temp[i] = array[i];
}
// mid-right 的序列进行逆向复制,这样就不用考虑多出元素的情况
for (i = mid + 1; i <= right; i++)
{
temp[right + mid + 1 - i] = array[i];
}
while (t <= right)
{
// 比较后复制到原序列中
if (temp[s1] < temp[s2])
array[t++] = temp[s1++];
else
array[t++] = temp[s2--];
}
}
主函数进行测试
int main()
{
int array[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
int temp[10] = { 0 };
int i = 0;
cout << "前:";
for (; i < 10; i++)
cout << array[i] << " ";
cout << endl;
doSort(array, temp, 0, 9);
cout << "后:";
for (i = 0; i < 10; i++)
cout << array[i] << " ";
cout << endl;
return 0;
}