当一个数组有序时,要向其中插入元素,可以先使用二分搜索查找其要插入的位置,位置确定后可以执行插入操作。
其中二分搜索的循环体如下(部分代码,具体见文章最后):
while(low<=high){//循环条件
mid = (low+high)/2;
if(a[mid]<val){
low = mid+1;
}else if(a[mid]>val){
high = mid-1;
}else{
insert(a,last,mid,val);//a[mid]==val,执行插入操作
return;
}
}
循环体的循环条件是low<=high
,如果碰到a[mid]==val
则可以执行插入操作。将待插入的元素放到新数组的mid位置(mid+1位置也可);然而并不能总是碰到a[mid]==val的情况,因为数组中很大可能不存在和待插入的元素相同的元素。这个时候待插入元素的位置很可能不是mid,看下面例子:
0 | 1 | 2 | 3 |
---|---|---|---|
1 | 4 | 5 | 6 |
上面是一个数组,假设要插入元素2,代码运行如下:
//循环1
mid = (0+3)/2=1;
a[1]>2 => low=0, high=mid-1=0
//循环2
mid=(0+0)/2=0;
a[0]<2 => low=mid+1=1,high=0
//停止
当循环停止的时候mid==0
,但这个时候在mid的位置插入元素是不对的,但处理方式也很简单,即如果循环的停止条件不是a[mid]==val的话,要比较a[mid]的值跟待插入的元素比较大小,如果小则在后面插入,如果比待插入的元素大则在前面插入,如下:
if(a[mid]<val){
insert(a,last,mid+1,val);
}else{
insert(a,last,mid,val);
}
下面是Leetcode上的一道题目,合并两个有序数组:
Merge Sorted Array
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.
Note:
You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively.
解答代码如下:
//在第targetIndex个位置插入val,插入后下标为targetIndex,
void insert(int* nums1,int lastIndex,int targetIndex,int val){
int j;
for(j=lastIndex;j>=targetIndex;j--){
nums1[j+1] = nums1[j];
}
nums1[targetIndex] = val;
}
//二分搜索查找插入位置,并插入
void binaryInsert(int* a,int high,int low,int val){
int mid;
int last = high;
if(a[high]<=val){
a[high+1] = val;
return;
}
while(low<=high){
mid = (low+high)/2;
if(a[mid]<val){
low = mid+1;
}else if(a[mid]>val){
high = mid-1;
}else{
insert(a,last,mid+1,val);
return;
}
}
if(a[mid]<val){
insert(a,last,mid+1,val);
}else{
insert(a,last,mid,val);
}
}
//合并两个已经排序的数组,初始元素分别为m和n个
//使用折半查找
void merge(int* nums1, int m, int* nums2, int n) {
int i;
if(m==0){
for(i=0;i<n;i++){
nums1[i] = nums2[i];
}
return;
}
if(n==0){
return;
}
for(i=0;i<n;i++){
binaryInsert(nums1,m-1,0,nums2[i]);
m++;
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/x_i_y_u_e/article/details/46721763