数组合并
题目描述
编写一个程序,将两个有序数组合并成一个更大的有序数组,要求时间复杂度为O(n)。
输入
多组数据输入,每组输入包括两行,每行第一个数字为数组长度n,然后输入n个有序整数。
输出
输出合并后的数组(升序),每组输出用一个空行隔开。
样例输入 Copy
3 1 3 5 3 2 4 6 2 1 2 4 3 4 5 6
样例输出 Copy
1 2 3 4 5 6 1 2 3 4 5 6
其实这就是二分查找的升级版,两个数组都是有序的,我们可以以其中任何一个数组为插入数据的对象,然后遍历另一个数组,如果比当前范围(left-right)的最小的要小,则数组往后移,将这个数放入目前范围内最小的位置;
若比当前范围内最大的数要大,则将这个数组目前最大范围的最大数后面的数往后移,再将这个数放到目前范围最大的位置;
上述两种情况都是数字不在范围内,如果数字在范围内,即x>a[left]&&x<a[mid] 或者x>a[mid]&&x<a[right],则不断缩小范围,直到出现上述两种情况;
用一个全局变量来保存当前已经放了几个数,因为每放一次,数组的长度就会变化,
代码如下:
#include<stdio.h>
int count=0;//记录数组的变化长度
void move(int *a,int n,int k){
int i=n-1;
for(;i>=k;i--){
a[i+1]=a[i];
}
}
int binary_search(int *a,int n,int x){
int left=0,right=n-1;
int mid;
while(left<=right){
mid=(left+right)/2;
if(x<=a[left]){//比当前区间最小的小
move(a,n,left);//数组后移
a[left]=x;
count++;
return left;
}
if(x>=a[right]){//比当前区间最大的大
move(a,n,right);
a[right+1]=x;
count++;
return right+1;
}
if(x>a[left]&&x<a[mid]){//在区间范围内
right=mid-1;
}else if(x>a[mid]&&x<a[right]){
left=mid+1;
}
}
return -1;
}
int main(){
int n,q;
while(scanf("%d",&n)!=EOF){
int s[1000],t[5000],index;
count=0;
for(int i=0;i<n;i++)
scanf("%d",&s[i]);
scanf("%d",&q);
for(int i=0;i<q;i++){
scanf("%d",&t[i]);
index=binary_search(s,n+count,t[i]);
//printf("%d\n",index);
}
for(int i=0;i<n+count;i++){
printf("%d%c",s[i],i==n+count-1?'\n':' ');
}
printf("\n");
}
return 0;
}
第一次写博客,多多关照呀呀!!!