基本思想:
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
分而治之
合并相邻的子序列:
#include <iostream>
using namespace std;
//将两个有序数列a[first...mid]和a[mid+1...last]合并。
void mergeArray(int a[], int first, int mid, int last, int temp[])
{
int i = first; // 第一个有序序列的开始下标
int j = mid + 1; // 第2个有序序列的开始下标
int length = 0;
// 合并两个有序序列
while (i<=mid && j<=last)
{
// 找二者中比较小的数
if (a[i] < a[j])
{
temp[length] = a[i];
i++;
}
else
{
temp[length] = a[j];
j++;
}
length++;
}
// 还剩下一个有序序列中有数据
while (i <= mid)
{
temp[length] = a[i];
i++;
length++;
}
while (j <= last)
{
temp[length++] = a[j++];
}
// 覆盖原来位置的无序序列
for (int i = 0; i < length; ++i)
{
// 找到原来 的第一个有序序列的开始位置 - 开始覆盖
a[first + i] = temp[i];
}
}
//归并排序
void mergeSort(int a[], int first, int last, int temp[])
{
// 递归结束的条件
if (first == last)
{
return;
}
// 从中间位置拆分
int mid = (first + last) / 2;
// 拆分
// 左半边
mergeSort(a, first, mid, temp);
// 右半边
mergeSort(a, mid + 1, last, temp);
// 合并两个有序序列
mergeArray(a, first, mid, last, temp);
}
#if 0
void main()
{
//定义整型数组
int array[] = { 12, 5, 33, 6, 10 };
//计算数组长度
int len = sizeof(array) / sizeof(int);
//遍历数组
cout<<"待排序数组序列:\t\t";
for (int i = 0; i < len; ++i)
{
cout << array[i] << "\t";
}
cout << endl;
//创建合适大小的临时数组
int *p = new int[sizeof(int)* len];
if (p == NULL)
{
return;
}
mergeSort(array, 0, len - 1, p);
delete[] p;
//遍历
cout<<"归并排序之后的序列:\t";
for (int i = 0; i < len; ++i)
{
cout << array[i] << "\t";
}
cout << endl;
system("pause");
}
#endif
最后
归并排序是稳定排序,它也是一种十分高效的排序,能利用完全二叉树特性的排序一般性能都不会太差。从上文的图中可看出,每次合并操作的平均时间复杂度为O(n),而完全二叉树的深度为|log2n|。总的平均时间复杂度为O(nlogn)。而且,归并排序的最好,最坏,平均时间复杂度均为O(nlogn)。