题目:
有两个排序的数组A1和A2,内存在A1的末尾有足够多的空余空间容纳A2.请实现一个函数,把A2中的所有数字插入到A1中,并且所有的数字都是有序的。
实现1:返回新数组
要点: 要返回一个新数组,这个数组在函数中需要用new的方式申请内存,这样的数组存储与堆中,在函数返回后并不会销毁,并且要在函数体外自行delete;如果数组在函数中使用普通变量的形式初始化,这样的数组存储在栈中,在函数返回后会销毁,导致函数体外访问异常;
一句话就是不能返回局部变量的指针或者引用!
#include <iostream>
using namespace std;
int* merge(int a[],int la, int b[],int lb)
{
if(a == nullptr)
{
return b;
}
else if(b == nullptr)
{
return a;
}
else
{
int *c = new int[la + lb];
int pa=0,pb=0,pc;
while(pa<la || pb<lb)
{
if (b[pb] == NULL || a[pa] <= b[pb])
{
c[pc++] = a[pa++];
}
else
{
c[pc++] = b[pb++];
}
}
return c;
}
}
int main(){
system("cls");
int arr1[] = {5, 13, 55, 88, 123, 425, 674};
int arr2[] = {2, 8, 12, 33, 68, 231, 444, 567};
int *arr3 =merge(arr1, 7, arr2, 8);
for (int i = 0; i < 15;i++){
cout << *(arr3 + i) << endl;
}
delete[] arr3;
}
实现2:从前往后修改原数组
思路:a、b两个有序数组合并到a中。
(1)若b为空 则退出函数。
(2)若当前数组长度<合并后总长度,则循环判断
①b已经遍历完 退出函数;
②a已经遍历完,循环把b插入到a中。
③a[pa]>b[pb],将a往后移再插入b
④a[pa]<b[pb],判断下一个a
#include <iostream>
using namespace std;
//从前往后
void merge1(int * a,int la,const int *b,int lb)
{
int pa = 0, pb = 0;
int wholeLength = la + lb;//总长度
int newLenght = la;//当前长度
if(b == nullptr)
{
return;
}
while(newLenght < wholeLength)
{
//数组b已经遍历完
if(b == nullptr)
{
return;
}
//数组a已经遍历完,直接插入b
else if(pa-pb==la)
{
a[pa++] = b[pb++];
newLenght++;
}
//a>b,后移并插入b
else if(a[pa]>b[pb])
{
for (int i = newLenght; i > pa;i--)
{
a[i] = a[i-1];
}
a[pa++] = b[pb++];
newLenght++;
}
//a<b,不做操作,数组a判断下一个数字
else
{
pa++;
}
}
}
void test(char * testName ,int * a,int la,const int *b,int lb)
{
cout << testName << endl;
cout << "merge resule:" << endl;
merge1(a, la, b, lb);
for (int i = 0; i < la + lb;i++)
{
cout << a[i]<<" ";
}
cout << endl;
}
//a为空
void test1(){
int la = 0;
int lb = 8;
int length = la+lb;
int arr1[length];
int arr2[lb] = {2, 8, 12, 33, 68, 231, 444, 567};
test("test01", arr1, la, arr2, lb);
}
//b为空
void test2(){
int la = 7;
int lb = 0;
int length = la+lb;
int arr1[length] = {5, 13, 55, 88, 123, 425, 674};
int arr2[lb];
test("test02", arr1, la, arr2, lb);
}
//a和b一样长
void test3(){
int la = 7;
int lb = 7;
int length = la+lb;
int arr1[length] = {5, 13, 55, 88, 123, 425, 674};
int arr2[lb] = {15, 33, 75, 89, 123, 415, 6884};
test("test03", arr1, la, arr2, lb);
}
//a比b长
void test4(){
int la = 7;
int lb = 3;
int length = la+lb;
int arr1[length] = {5, 13, 55, 88, 123, 425, 674};
int arr2[lb] = {3,44,121};
test("test04", arr1, la, arr2, lb);
}
//b比a长
void test5(){
int la = 3;
int lb = 8;
int length = la+lb;
int arr1[length] = {5, 88, 674};
int arr2[lb] = {2, 8, 12, 33, 68, 231, 444, 567};
test("test05", arr1, la, arr2, lb);
}
int main()
{
system("cls");
test1();
test2();
test3();
test4();
test5();
}
实现3:从后往前修改原数组
思路:定义两个指针,oriEnd指向原数组a的末尾,newEnd指向合并后数组的末尾。
思路和实现2差不多,只是指针是往前移动。
#include <iostream>
using namespace std;
//从后往前
void merge2(int * a,int la,const int *b,int lb)
{
int newEnd = la + lb-1;
int oriEnd = la-1;
int pb = lb-1;
if(lb == 0)
{
return;
}
else
{
while(oriEnd>=0 || pb>=0)
{
if(oriEnd<0)
{
a[newEnd--] = b[pb--];
}
else if(pb<0)
{
return;
}
else if(b[pb]>=a[oriEnd])
{
a[newEnd--] = b[pb--];
}else
{
a[newEnd--] = a[oriEnd--];
}
}
return;
}
}
void test(char * testName ,int * a,int la,const int *b,int lb)
{
cout << testName << endl;
cout << "merge resule:" << endl;
merge2(a, la, b, lb);
for (int i = 0; i < la + lb;i++)
{
cout << a[i]<<" ";
}
cout << endl;
}
//a为空
void test1(){
int la = 0;
int lb = 8;
int length = la+lb;
int arr1[length];
int arr2[lb] = {2, 8, 12, 33, 68, 231, 444, 567};
test("test01", arr1, la, arr2, lb);
}
//b为空
void test2(){
int la = 7;
int lb = 0;
int length = la+lb;
int arr1[length] = {5, 13, 55, 88, 123, 425, 674};
int arr2[lb];
test("test02", arr1, la, arr2, lb);
}
//a和b一样长
void test3(){
int la = 7;
int lb = 7;
int length = la+lb;
int arr1[length] = {5, 13, 55, 88, 123, 425, 674};
int arr2[lb] = {15, 33, 75, 89, 123, 415, 6884};
test("test03", arr1, la, arr2, lb);
}
//a比b长
void test4(){
int la = 7;
int lb = 3;
int length = la+lb;
int arr1[length] = {5, 13, 55, 88, 123, 425, 674};
int arr2[lb] = {3,44,121};
test("test04", arr1, la, arr2, lb);
}
//b比a长
void test5(){
int la = 3;
int lb = 8;
int length = la+lb;
int arr1[length] = {5, 88, 674};
int arr2[lb] = {2, 8, 12, 33, 68, 231, 444, 567};
test("test05", arr1, la, arr2, lb);
}
int main()
{
system("cls");
test1();
test2();
test3();
test4();
test5();
}