一维数组——数组的插入

【问题描述】

编写程序,从任意n个数(升序排列)中插入某一个数k,使得数列仍然保持升序排列。

【输入形式】

输入分3行:第一行为n的值,第二行为n个数,第三行为要插入的数k。

【输出形式】

整个数列(n+1个数)

【样例输入1】:

5

1 2 3 4 6

0

【样例输出1】

0 1 2 3 4 6

【样例输入2】

5

1 2 3 4 6

5

【样例输出2】

1 2 3 4 5 6

【样例输入3】

5

1 2 3 4 6

8

【样例输出3】

1 2 3 4 6 8

【样例说明】

在数列1、2、3、4、6中插入0,整个数列变为0、1、2、3、4、6;如果是在数列中插入5,整个数列变为1、2、3、4、5、6;如果插入的是8,则整个数列变为1、2、3、4、6、8

解析

这道题目思路不难,就是注意一些细节就行了:
1、待插入的数字比原数列的任何数都大或比原数列任何数都小(特殊情况优先处理)
2、原数列是升序排序的,可以用二分查找提高检索效率。但二分查找有一定的局限性,所以第一点就要特殊情况优先处理。
3、原数列有若干项的数字是相同的,而待插入的数字也和这些项一样,要注意防止二分查找陷入死循环。例如:

10
1 3 5 7 7 7 7 7 7 9
7

待插入的数字7和原数列的某些连续项相同,要注意二分查找的时候防止陷入死循环。
4、当找到下标之后,要注意是插入左边还是插入右边。我写程序的时候是不断通过吧目标下标的右侧元素往右移动一个单位来实现数组元素的插入,也就是说默认是插入了目标下标的右边。所以要写一个判断,看看目标下标所对应的元素和待插入数字的大小;如果目标下标所对应的元素比待插入的数字大,那么就先将它们交换,再进行下一步右移操作。

例如:

10
10 20 30 40 50 60 70 80 90 100
75

经过二分查找之后,最终待插入的下标mid=8,a[mid]=80,而待插入的数字a[11]=75<80,如果直接进行移动操作:

for(int i=n;i>mid;i--)
		swap(a[i],a[i+1]);

那么最终的结果就是

10 20 30 40 50 60 70 80 75 90 100

所以要先进行交换,因为待插入的数字比目标下标对应的元素小。

	if(a[n+1]<a[mid]) swap(a[n+1],a[mid]);

那么最终的结果就是

10 20 30 40 50 60 70 75 80 90 100

代码

#include<iostream>
using namespace std;
const int N=10002;
int n,a[N];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	cin>>a[n+1];
	int l=1,r=n,mid;
	while(l<=r)
	{
		mid=(l+r)/2;
		if(a[n+1]>a[mid]) l=mid+1;
		else if(a[n+1]<a[mid]) r=mid-1;
		else break;//注意事项的第三点
	}
	mid=(l+r+1)/2;
	if(a[n+1]<a[mid]) swap(a[n+1],a[mid]);//注意事项第四点
	for(int i=n;i>mid;i--)
		swap(a[i],a[i+1]);
	for(int i=1;i<=n+1;i++)
		cout<<a[i]<<" ";
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值