题目:数组a[0,m] 和 a[m+1,m+n],都分别有序。将其merge成有序数组a[0,m+n]。(注:这里用的两个数组是分别有序的)
受这个题目启发,简单总结了一下Merge Sort:
1。空间复杂度为O(m+n):
MergeSort算法思想大家比较熟悉,如果空间复杂度是O(m+n)的话,只需临时申请一段m+n个元素的数组空间,分别比较a数组和b数组中已经排序的最小值,取出放入c数组中,当a或b数组中其中一个中的元素取完后,另一个数组中剩下的元素直接放入数组c后面即可,现在已经完成归并排序,如果只是将c数组作为临时数组,最后可将c中的元素转移到a和b的空间中。
代码如下:
#include
#include
#include
using namespace std;
//将有序数组a[]和b[]合并到c[]中
//比较好理解,不再写注释
void MergeSort(int a[], int n, int b[], int m, int c[])
{
int i=0, j=0, k=0;
while (i < n && j < m)
{
if (a[i] < b[j])
c[k++] = a[i++];
else
c[k++] = b[j++];
}
while (i < n)
c[k++] = a[i++];
while (j < m)
c[k++] = b[j++];
}
int main()
{
int a[] = {1,3,5,7,9};
int b[] = {2,4,6,8,10};
int m = sizeof(a)/sizeof(int);
int n = sizeof(b)/sizeof(int);
int c[10] = {0};
MergeSort(a, m, b, n, c); //当数组作为参数时,只需将名字传入,其实是传指针。
for(int i = 0; i<10; i++)
printf(" %d ",c[i]);
return 0;
}
我的思路是:在不借助辅助数组的情况下,在a和b数组空间上直接Merge。
因为a和b都已经排好序,首先比较a[0,m]和a[m+1,m+n]的第一个元素,如果将小的放在a[0],并将a[m+1,m+n]进行重排序(插入排序),当a[0,m]填满了的时候,最后一次对a[m+1,m+n]插入排序后,即完成了归并排序。
代码如下:
#include
#include
#include
using namespace std;
//将两个有序数组用O(1)的空间复杂度实现Merge排序
void MergeSort(int a[], int m, int n)
{
int i = 0;
while(i <= m)
{
//当a[i] > a[n]时,两元素交换,使得相对较小的元素在a[i]中。
if(a[i] > a[n])
{
int temp = a[i];
a[i] = a[n];
a[n] = temp;
//对数组后半部分新添加的值插入到有序数组中,成新的有序数组
for(int j = 0; j< n; j++)
{
if(a[n+j] > a[n+j+1])
{
temp = a[n+j];
a[n+j] = a[n+j+1];
a[n+j+1] = temp;
}
else
break;
}
i++;
}
else
i++;
}
}
int main()
{
//简单测试用例
int a[] = {1,3,5,7,9,1,4,6,8,10};
int m = 4;
int n = 5;
MergeSort(a, m, n );
for(int i = 0; i<10; i++)
printf(" %d ",a[i]);
return 0;
}