您的位置:首页 > 其它

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

2015-07-02 07:57 686 查看
当一个数组有序时,要向其中插入元素,可以先使用二分搜索查找其要插入的位置,位置确定后可以执行插入操作。

其中二分搜索的循环体如下(部分代码,具体见文章最后):

[code]    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,代码运行如下:

[code]//循环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]的值跟待插入的元素比较大小,如果小则在后面插入,如果比待插入的元素大则在前面插入,如下:

[code]    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.

解答代码如下:

[code]//在第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++;
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: