归并排序
思想:递的过程就是在缩小数据规模;在归的过程中,进行数据合并,需要额外的内存空间,将两个小段有序的序列,合并为成大段的序列,达到排序的效果。
时间复杂度分析:
时间复杂度从两个方面分析:递的过程和两个小数列排序的过程。
递的过程:将数列分解为平衡二叉树,高度为O(logn);
排序的过程:排序需要处理n个元素,所以时间复杂度为O(n);
总的时间复杂度为:O(n*logn);
空间复杂度分析:
递归调用的开销是O(logn);
合并两个小段的过程分配的内存为size,O(n);
仔细分析这两个过程,空间复杂度为:O(n) + O(logn) = O(n)
稳定性分析:
归并排序是稳定的。比如,51(1) 51(2),1进行合并,合并后为1 51(1) 51(1)
// 递归只需要考虑水平一层即可。
// 首先看递归的参数,要有缩小的趋势
// 再写出递归结束的条件
// 再写出递归要完成的事
// [begin,mid] [mid+1,end]
void MergeS(int arr[],int begin,int mid,int end,int *p)
{
int i = begin;
int j = mid + 1;
int index = 0;
// 将比较的两个小数列按序合成一个大数列
while (i <= mid && j <= end)
{
if (arr[i] <= arr[j])
{
p[index++] = arr[i++];
}
else
{
p[index++] = arr[j++];
}
}
// 如果右边的元素都放进去了,把左边的元素放入临时数组中
while (i <= mid)
{
p[index++] = arr[i++];
}
// 同理将右边数据放入临时数组中
while (j <= end)
{
p[index++] = arr[j++];
}
// 最后将临时空间中的数据放入原数组中
for (i = begin, index = 0; i <= end; i++, index++)
{
arr[i] = p[index];
}
// 最后删除 临时空间
}
void MergeSort1(int arr[], int begin, int end,int *p)
{
if (begin >= end)
{
return;
}
int mid = (begin + end) / 2;
// 先递
MergeSort1(arr, begin, mid,p);
MergeSort1(arr, mid + 1, end,p);
// 开始处理归
// 对树中的数据进行排序并合并
MergeS(arr, begin,mid, end,p);
}
void MergeSort1(int arr[], int size)
{
int *p = new int[size];
MergeSort1(arr, 0, size - 1,p);
delete[] p;
}
int main()
{
srand(time(0));
int arr[10];
for (int i = 0; i < 10; i++)
{
arr[i] = rand() % 100;
cout << arr[i] << " ";
}
cout << endl;
MergeSort1(arr, 10);
for (int i : arr)
{
cout << i << " ";
}
cout << endl;
system("pause");
return 0;
}
本文含有隐藏内容,请 开通VIP 后查看