顺序表---两个非递减数组元素合并

合并两个有序数组,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]);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值