有两个有序数组,int nums1[ ] = { 1,2,3,0,0,0 }和int nums2[ ] = { 2,5,6 }。不开辟新空间的情况下将nums2数组中的内容合并到nums1中,结果为:nums1[ ] = { 1,2,2,3,5,6 },本文采用两种方法实现合并。
方法1(比较法)
从两个数组的最后一位有效元素开始比较,大的元素拷贝到nums1的最后一位,并依次往前拷贝。具体操作如下:
代码实现:
#include<stdio.h>
int main()
{
int nums1[] = { 1,2,3,0,0,0 };
int nums2[] = { 2,5,6 };
int m = 3;//标记数组中涉及到对比的元素的个数
int n = 3;
int i = (m + n)-1;//表示nums1数组中最后一个元素的下标
int end1 = m-1;//最后一位有效数组的下标
int end2 = n-1;
while (end1 >= 0 && end2 >= 0)//循环判断标志
{
if (nums1[end1] > nums2[end2])//若nums1[end1]大于nums2[end2]
{
nums1[i] = nums1[end1];//把nums1[end1]的值放到nums1数组的i位置中
i--;//i往前移一位
end1--;//end1往前移一位,便于nums1的前一个元素与nums2[end2]进行比较
}
else//nums1[end1]小于或者等于nums2[end2]的情况
{
nums1[i] = nums2[end2];//原理同上
i--;
end2--;
}
}
//若进此次循环,表示nums1已经遍历完毕,而nums2还有元素没有放到nums1中
while (end2 >= 0)
{
//到这里,则表示nums2中剩余的元素是最小的
nums1[i] = nums2[end2];//因此直接拷贝到nums1前面的位置即可。
i--;
end2--;
}
i = 0;
for (i = 0; i < (m + n); i++)//打印数组
{
printf("%d ", nums1[i]);
}
return 0;
}
运行结果:
方法1(元素插入法)
首先元素插入数组的思想如下(假设数组后面都是0):
用代码实现就是从下标5的位置开始,把下标5的值赋给下标为6的元素,之后移动到下标为4处,将下标4的元素的值赋给下标为5的元素:
回到数组合并,合并的思路:两组数组都从头开始比较。
1.若nums2中的元素较小,则插到与nums1元素的前面。
2.若nums2中的元素较大且小于nums1的下一个元素,则插到nums1元素的后面。
3.若nums2中的元素都比nums1中的元素大,则直接将nums2中剩下的元素嫁接到nums1数组的后面即可。
代码实现:
#include<stdio.h>
int main()
{
int nums1[] = { 1,2,3,0,0,0 };
int nums2[] = { 2,5,6 };
int m = 3;//标记数组中涉及到对比的元素的个数
int n = 3;
int a1 = 0;//a1和a2表示下标,用于遍历数组中要对比的元素
int a2 = 0;
while (a1 < m && a2 < n)//判断结束标志
{
if (nums1[a1] > nums2[a2])//若nums1[a1]比nums2[a2]要大
{
int start = m - 1;
while (start >= a1)
{
nums1[start + 1] = nums1[start];//从nums1数组中a1处开始整体向后移动
start--;
}
nums1[a1] = nums2[a2];//将nums2[a2]的值覆盖nums1[a1],达到插入的效果
a2++;
m++;//m随着nums1数组的有效元素增多而增大
}
//判断nums2[a2]大于nums1[a1]且小于nums1[a1 + 1]),
//以及两元素相等的情况,都插入到nums1[a1]的后一位
else if ((nums1[a1] < nums2[a2] && nums2[a2] < nums1[a1 + 1]) || nums1[a1] == nums2[a2])
{
int start = m - 1;
while (start >= a1)
{
nums1[start + 1] = nums1[start];//从nums1数组中a1处开始整体向后移动
start--;
}
nums1[a1 + 1] = nums2[a2];//将nums2[a2]的值覆盖nums1[a1],达到插入的效果
a2++;
m++;//m随着nums1数组的有效元素增多而增大
}
else//若nums1[a1]小于nums2[a2],则nums1[a1]往后走
{
a1++;
}
}
if (nums1[a1] == 0)//当nums1中的元素以及遍历完后,或者nums1中没有有效元素
{
int i = 0;
for (i = a2; i < n; i++)
{
nums1[a1] = nums2[i];//则直接将nums2的元素拷贝到nums1的末尾
a1++;
}
}
int sz = sizeof(nums1) / sizeof(nums1[0]);
int i = 0;
for (i = 0; i < sz; i++)//打印
{
printf("%d ", nums1[i]);
}
return 0;
}
运行结果:
结语:
虽然方法1要比方法2简单得多,但是方法2的插入元素的思路在c语言中的应用也很广泛,因此方法2的逻辑也很重要。另外如果本文对你起到了帮助,希望可以点赞👍+关注😎+收藏👌哦!如果有遗漏或者有误的地方欢迎大家在评论区补充~!!谢谢大家!!( ̄︶ ̄)↗