插入元素到有序数组,二分搜索查找插入位置

当一个数组有序时,要向其中插入元素,可以先使用二分搜索查找其要插入的位置,位置确定后可以执行插入操作。
其中二分搜索的循环体如下(部分代码,具体见文章最后):

    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,看下面例子:

0123
1456

上面是一个数组,假设要插入元素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++;
    }
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值