需求:有两个非递减排序的数组A1和A2,内存在A1的末尾有足够多的空余空间容纳A2,请实现一个函数,把A2中的所有数字插入A1中,并且所有的数字都是排序的。
例如数组A1{ 1,5,7,8,9,17,20 }和数组A2{ 0,2,4,6,7,17,18,23,25 },合并后的结果应为{ 0,1,2,3,5,7,7,8,9,17,17,18,20,23,25 }。
分析:

思路一

直接从两个数组头部开始合并。
1.从A2开始遍历第一个数字;
2.由于A1中如果数字比A2小的话,A1和A2的数字都不需要变动,因此查找A1中第一个比A2当前数字的小的元素;
3.如果找到了A1中的最后一个数字都比当前A2的数字小,说明A2当前数字以及后面所有的数字都比A1的最后一个数字大,直接把A2当前的数字以及后面所有的数字都依次放到A1最后一个元素的后面即完成合并;
4.如果找到了A1中的其中一个数字比A2大,则把A1的这个数字以及后面的所有数字都往后移动1个位置;
5.把A2的这个数字放到步骤2中找到的A1的元素的位置,完成了A2的第1个数字的合并;
6.继续开始A2的下一个数字,重复步骤2直到数组A2的最后一个数字都已经被放到A1中。
从头开始合并发,由于要在遍历数组A2的同时还要查找A1中比A2大的元素,并且还要移动A1的元素,假设待合并的两个数组的数字个数分别为m和n,则时间复杂度为O(m*n)。
见示例代码mergeArrayFromHead。

思路二

从两个数组的尾部开始合并。
1.由于合并后的数组长度是A1的长度加上A2的长度,所以可以获取最终数组的最后一个数字的位置;
2.同时从数组A1和A2的最后一个数字开始往前遍历;
3.如果A2的当前数字比A1大,说明A2数组的这个数字排在靠后的位置,所以最终数组的最后一个位置应该填上A2数组的数字,然后A2往前遍历下一个数字;否则,最终数组的最后一个位置应该填上A1数组的数字,然后A1往前遍历下一个数字。
4.当确定了最终数组的最后一个位置的数字之后,继续确定倒数第二个数字的值,通过步骤3结果比较当前A2和A1的数组的数字。继续步骤3。
5.当数组A2的最后一个数字都已经被放到最中的数组A1中之后,任务结束。
从尾开始替换法,由于只需要同时遍历数组A1和A2就完成了处理,假设待合并的两个数组的数字个数分别为m和n,则时间复杂度为O(m+n)。
见示例代码mergeArrayFromTail。
c++示例代码:
1 #include2 3usingnamespace std; 4 5/************************************************************************/ 6/* @brif 从头开始合并数组B的数字到数组A中 7/* @param arrA 非递减排序的整数数组A 8/* @param numA 数组A的数字的数量 9/* @param arrB 非递减排序的整数数组B 10/* @param numB 数组B的数字的数量 11/* @return true表示合并成功 false表示合并失败 12/************************************************************************/ 13bool mergeArrayFromHead(int* arrA,constint numA,constint* arrB,constint numB) 14{ 15if (!arrA || !arrB || numA