假设sz1和sz2是有序数组,同时sz1有足够的空间容纳sz2,要实现sz1和sz2的合并,不允许开辟新的数组空间,同时要求时间复杂度为O(n),空间复杂度为O(1).
同样采用尾指针的方法:
#include <iostream>
#include <stdlib.h>
using namespace std;
void paixu(int sz1[], int len_sz1, int sz2[], int len_sz2)
{
int *pSz1NewEnd = sz1+len_sz1+len_sz2-1; //指向融合后的sz1的尾部
int *pSz1End = sz1+len_sz1-1; //指向数组1的尾部
int *pSz2End = sz2+len_sz2-1; //指向数组2的尾部
//从尾部开始,逐个比较
//分为三种情况:
//1、sz1第一个元素大于sz2第一个元素,则当sz2最后一个元素插入后,肯定有pSz1NewEnd == pSz1End,循环结束
//2、sz1第一个元素等于sz2第一个元素,此时pSz1End和pSz2End指针实际上已经指向数组首地址的前一个元素了
//3、sz1第一个元素小于sz2第一个元素,此时pSz1End指针实际上已经指向数组首地址的前一个元素,2和3单独考虑
while(pSz1NewEnd > pSz1End)
{
//比较策略:将较大的数放到*pSz1NewEnd处,如果相等则一同放置
if(*pSz1End > *pSz2End)
{
*pSz1NewEnd-- = *pSz1End--;
}
else if(*pSz1End < *pSz2End)
{
*pSz1NewEnd-- = *pSz2End--;
}
else //equals
{
*pSz1NewEnd-- = *pSz1End--;
*pSz1NewEnd-- = *pSz2End--;
}
//针对2和3的情况单独处理
if(pSz1End < sz1)
{
if(pSz2End >= sz2)
{//针对情况2,如果sz2中还有元素未插入,则将所有元素一同插入
while(pSz2End > sz2)
{
*pSz1NewEnd-- = *pSz2End--;
}
*pSz1NewEnd = *pSz2End; //插入第一个元素
return;
}
//针对情况3,如果sz2的元素已经全部插入完毕
return;
}
}
}
//假设不允许开辟新的存储空间,直接在sz1上操作
//时间复杂度要求0(n)
int main()
{
int sz1[256] = {2, 5, 7, 10, 23, 27};
int sz2[] = {1, 6, 11, 19, 24, 29, 32};
int len_sz1 = 6;
int len_sz2 = sizeof(sz2)/sizeof(int);
paixu(sz1, len_sz1, sz2, len_sz2);
for(int i=0; i<len_sz1+len_sz2; i++)
{
cout<<sz1[i]<<' ';
}
cout<<endl;
system("PAUSE");
return 0;
}