插入元素到有序数组,二分搜索查找插入位置
2015-07-02 07:57
686 查看
当一个数组有序时,要向其中插入元素,可以先使用二分搜索查找其要插入的位置,位置确定后可以执行插入操作。
其中二分搜索的循环体如下(部分代码,具体见文章最后):
循环体的循环条件是
上面是一个数组,假设要插入元素2,代码运行如下:
当循环停止的时候
下面是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] 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 |
[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++; } }
相关文章推荐
- LLBL Gen Pro 4.2 Lite 免费的对象关系映射开发框架与工具
- Python基础知识回顾
- 算法与数据结构八日谈之二——动态规划
- nyoj 1100 WAJUEJI which home strong! 【简单BFS】
- 破解NET的四大神器
- SendInput -- 鼠标移动
- 移动端web资源
- 20 款优秀的 Linux 终端仿真器
- 《C语言陷阱与缺陷》读书笔记 之 运算符优先
- Section 12 GUI
- windows下搭建cocos2d-x环境
- rndc reload 执行过程
- virtualbox中ubuntu和windows共享文件夹设置
- 安卓棒棒糖,敲出国内ROM厂商真面目
- 开始转向互联网,后面每两周发一篇
- 基于google protobuf 的 socket udp 通信
- 【Xamarin】MonoTouch - iOS 使用 UIImagePickerController 打开图片库和相机选择图片修改头像
- Swift开发iOS app初学一周体会
- Swift computed property可计算属性详解
- OSChina 周四乱弹 —— 不写代码,还能挖钻石