合并两个有序数组,nums1数组有足够空间,将nums2数组元素合并到nums1数组中,两个数组元素都是非递减(非严格递增)的顺序排列。n1、n2表示两个数组待排序的数据。
int nums1[] = { 1,2,3,0,0,0 };
int n1 = 3;//待排数据个数,多余空间置0
int nums2[] = { 4,5,6 };
int n2 = 3;
题目要求将nums2中的元素按照非递减的规则合并到nums1数组中,所以我们合并后的nums1数组应该是一个非递减的顺序,由于nums1数组给出了能够容纳nums2元素和nums1元素的空间,我们对于nums1与nums2数组的尾部元素也就是最大的元素进行比较,较大者放到nums1的数组末尾位置,循环此操作直到nums1或者nums2访问到首位元素为终止(再继续可能出现数组越界的非法访问)。
那么我们使用一个函数PackedArray来完成这个合并操作:
void PackedArray(int* nums1, int n1, int* nums2, int n2);
非递减顺序,那么尾部元素最大,我们定义两个下标end1与end2,end1表示nums1的末位最大元素下标,end2表示nums2的末位最大元素下标。对于完整的nums1数组而言,它的末位下标也得拿出来,我们定义Pack作为该下标。
int end1 = n1 - 1;
int end2 = n2 - 1;
int Pack = n1 + n2 - 1;
那么基本进行的操作应该如下:比较大小,较大放在尾端,对应下标减1,然后接着比较......
if (nums1[end1] < nums2[end2])
nums1[Pack--] = nums2[end2--];
else
nums1[Pack--] = nums1[end1--];
循环的条件是什么呢?
注意:循环的条件可以是Pack>=0吗?不能!如下图演示:
Pack>0的这个条件,只能针对于极为特殊的两个数组元素的合并,并不能广泛适用!这种极为特殊的两个数组,他们的元素大小,是互相有来有往的。如[1,3,5,0,0,0] 和 [2,4,6]等。
所以我们在此处循环的正确条件是end1>=0&&end2>=0,主要就是保证数组不越界访问!
while (end1 >= 0 && end2 >= 0)
{
if (nums1[end1] < nums2[end2])
nums1[Pack--] = nums2[end2--];
else
nums1[Pack--] = nums1[end1--];
}
那么这个代码完整了吗?
void PackedArray(int* nums1, int n1, int* nums2, int n2)
{
int end1 = n1 - 1;
int end2 = n2 - 1;
int Pack = n1 + n2 - 1;
while (end1 >= 0 && end2 >= 0)
{
if (nums1[end1] < nums2[end2])
nums1[Pack--] = nums2[end2--];
else
nums1[Pack--] = nums1[end1--];
}
}
int main()
{
int nums1[] = { 1,2,3,0,0,0 };
int n1 = 3;//待排数据个数,多余空间置0
int nums2[] = { 4,5,6 };
int n2 = 3;
PackedArray(nums1, n1, nums2, n2);
for (int i = 0; i < 6; i++)
{
printf("%d ", nums1[i]);
}
}
其实也没有。
我们的循环条件只是规避了越界访问的一个风险,但是我们需要去验证, 这样操作完是否能够完成合并这个操作。
所以,我们仍然需要判断end2的数值,或者说创建的是指针,那就判断end2指向的位置。
while (end2 >= 0)
{
nums1[Pack--] = nums2[end2--];
}
那么代码就完善了。
整体代码如下:
void PackedArray(int* nums1, int n1, int* nums2, int n2)
{
int end1 = n1 - 1;
int end2 = n2 - 1;
int Pack = n1 + n2 - 1;
while (end1 >= 0 && end2 >= 0)
{
if (nums1[end1] < nums2[end2])
nums1[Pack--] = nums2[end2--];
else
nums1[Pack--] = nums1[end1--];
}
while (end2 >= 0)
{
nums1[Pack--] = nums2[end2--];
}
}
int main()
{
int nums1[] = { 1,2,3,0,0,0 };
int n1 = 3;//待排数据个数,多余空间置0
int nums2[] = { 4,5,6 };
int n2 = 3;
PackedArray(nums1, n1, nums2, n2);
for (int i = 0; i < 6; i++)
{
printf("%d ", nums1[i]);
}
}