二分查找整理
来源:互联网 发布:何炅主持的网络节目 编辑:程序博客网 时间:2024/06/01 08:56
二分查找
原博: here
1 //二分查找 2 int binarySearch(int arr[], int len, int key) 3 { 4 int left = 0; 5 int right = len - 1; 6 int mid; 7 8 while (left <= right) { 9 mid = (left + right) / 2;10 if (key < arr[mid]) {//key在左边11 right = mid - 1;12 } else if (arr[mid] < key) {//key在右边13 left = mid + 1;14 } else {15 return mid;16 }17 }18 return -1;19 }
二分查找变形
随着二分查找的进行,如果找到key并不结束循环的话,最终的结束状态会是right < left,并且right + 1 = left。
当数组中存在key时,根据二分区间选择的不同,这里又分为两种情况,如下图(key为2时),
当数组中不存在key时,最后仅有一种情况,即把图中的黄色框框去掉。
那么,可以找到
1 最后一个小于key的元素,1,
2 第一个大于等于key的元素,2,
3 最后一个小于等于key的元素,2,
4 第一个大于key的元素,5,
另外,如果存在多个key时,稍加判断,就可以找到
5 第一个与key相等的元素
6 最后一个与key相等的元素
1 查找最后一个小于key的元素
1 //1 查找最后一个小于key的元素 2 int findLastLess(int arr[], int len, int key) 3 { 4 int left = 0; 5 int right = len - 1; 6 int mid; 7 8 while (left <= right) { 9 mid = (left + right) / 2;10 if (key <= arr[mid]) {11 right = mid - 1;12 } else {13 left = mid + 1;14 }15 }16 return right;17 }
2 查找第一个大于等于key的元素
1 //2 查找第一个大于等于key的元素 2 int findFirstGreaterEqual(int arr[], int len, int key) 3 { 4 int left = 0; 5 int right = len - 1; 6 int mid; 7 8 while (left <= right) { 9 mid = (left + right) / 2;10 if (key <= arr[mid]) {11 right = mid - 1;12 }13 else {14 left = mid + 1;15 }16 }17 return left;18 }
3 查找最后一个小于等于key的元素
1 //3 查找最后一个小于等于key的元素 2 int findLastLessEqual(int arr[], int len, int key) 3 { 4 int left = 0; 5 int right = len - 1; 6 int mid; 7 8 while (left <= right) { 9 mid = (left + right) / 2;10 if (key < arr[mid]) {11 right = mid - 1;12 } else {13 left = mid + 1;14 }15 }16 return right;17 }
4 查找第一个大于key的元素
1 //4 查找第一个大于key的元素 2 int findFirstGreater(int arr[], int len, int key) 3 { 4 int left = 0; 5 int right = len - 1; 6 int mid; 7 8 while (left <= right) { 9 mid = (left + right) / 2;10 if (key < arr[mid]) {11 right = mid - 1;12 }13 else {14 left = mid + 1;15 }16 }17 return left;18 }
5 查找第一个与key相等的元素
1 //5 查找第一个与key相等的元素 2 int findFirstEqual(int arr[], int len, int key) 3 { 4 int left = 0; 5 int right = len - 1; 6 int mid; 7 8 while (left <= right) { 9 mid = (left + right) / 2;10 if (key <= arr[mid]) {11 right = mid - 1;12 } else {//arr[mid] < key13 left = mid + 1;14 }15 }16 //arr[right] < key <= arr[left]17 //right是最后一个小于key的18 //left是第一个大于等于key的19 if (left < len && arr[left] == key) {20 return left;21 }22 return -1;23 }
6 查找最后一个与key相等的元素
1 //6 查找最后一个与key相等的元素 2 int findLastEqual(int arr[], int len, int key) 3 { 4 int left = 0; 5 int right = len - 1; 6 int mid; 7 8 while (left <= right) { 9 mid = (left + right) / 2;10 if (key < arr[mid]) {11 right = mid - 1;12 } else {//arr[mid] <= key13 left = mid + 1;14 }15 }16 //arr[right] <= key < arr[left]17 //right是最后一个小于等于key的18 //left是第一个大于key的19 if (right >= 0 && arr[right] == key) {20 return right;21 }22 return -1;23 }
最后补一张图,辅助理解,
怎么记呢?
看到其它博客的总结,也不错,
http://www.cnblogs.com/luoxn28/p/5767571.html
但是我觉得不够清晰好记,这里我总结为:
只要记住上面两幅图就好了,哈哈...
其实,只要记住比较符号和返回值,其它的代码都一样,
1 while (left <= right) {2 mid = (left + right) / 2;3 if (key ? arr[mid]) {4 right = mid - 1;5 } else {6 left = mid + 1;7 }8 }9 return ?;
根据要求的值的位置,先确定比较符号,再确定返回值,
比较符号:左<=,右<
返回值:左right,右left
贴一个完整的测试代码吧,
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 //二分查找 5 int binarySearch(int arr[], int len, int key) 6 { 7 int left = 0; 8 int right = len - 1; 9 int mid; 10 11 while (left <= right) { 12 mid = (left + right) / 2; 13 if (key < arr[mid]) {//key在左边 14 right = mid - 1; 15 } else if (arr[mid] < key) {//key在右边 16 left = mid + 1; 17 } else { 18 return mid; 19 } 20 } 21 return -1; 22 } 23 24 //1 查找最后一个小于key的元素 25 int findLastLess(int arr[], int len, int key) 26 { 27 int left = 0; 28 int right = len - 1; 29 int mid; 30 31 while (left <= right) { 32 mid = (left + right) / 2; 33 if (key <= arr[mid]) { 34 right = mid - 1; 35 } else { 36 left = mid + 1; 37 } 38 } 39 return right; 40 } 41 42 //2 查找第一个大于等于key的元素 43 int findFirstGreaterEqual(int arr[], int len, int key) 44 { 45 int left = 0; 46 int right = len - 1; 47 int mid; 48 49 while (left <= right) { 50 mid = (left + right) / 2; 51 if (key <= arr[mid]) { 52 right = mid - 1; 53 } 54 else { 55 left = mid + 1; 56 } 57 } 58 return left; 59 } 60 61 //3 查找最后一个小于等于key的元素 62 int findLastLessEqual(int arr[], int len, int key) 63 { 64 int left = 0; 65 int right = len - 1; 66 int mid; 67 68 while (left <= right) { 69 mid = (left + right) / 2; 70 if (key < arr[mid]) { 71 right = mid - 1; 72 } else { 73 left = mid + 1; 74 } 75 } 76 return right; 77 } 78 79 //4 查找第一个大于key的元素 80 int findFirstGreater(int arr[], int len, int key) 81 { 82 int left = 0; 83 int right = len - 1; 84 int mid; 85 86 while (left <= right) { 87 mid = (left + right) / 2; 88 if (key < arr[mid]) { 89 right = mid - 1; 90 } 91 else { 92 left = mid + 1; 93 } 94 } 95 return left; 96 } 97 98 //5 查找第一个与key相等的元素 99 int findFirstEqual(int arr[], int len, int key)100 {101 int left = 0;102 int right = len - 1;103 int mid;104 105 while (left <= right) {106 mid = (left + right) / 2;107 if (key <= arr[mid]) {108 right = mid - 1;109 } else {//arr[mid] < key110 left = mid + 1;111 }112 }113 //arr[right] < key <= arr[left]114 //right是最后一个小于key的115 //left是第一个大于等于key的116 if (left < len && arr[left] == key) {117 return left;118 }119 return -1;120 }121 122 //6 查找最后一个与key相等的元素123 int findLastEqual(int arr[], int len, int key)124 {125 int left = 0;126 int right = len - 1;127 int mid;128 129 while (left <= right) {130 mid = (left + right) / 2;131 if (key < arr[mid]) {132 right = mid - 1;133 } else {//arr[mid] <= key134 left = mid + 1;135 }136 }137 //arr[right] <= key < arr[left]138 //right是最后一个小于等于key的139 //left是第一个大于key的140 if (right >= 0 && arr[right] == key) {141 return right;142 }143 return -1;144 }145 146 147 void test()148 {149 // int a[] = {0, 1, 2, 3, 4, 5, 6};150 int a[] = {0, 1, 2, 2, 2, 5, 6};151 int len = 7;152 int key = 2;153 154 int index;155 156 int i;157 for (i = 0; i < len; ++i) {158 printf("%d ", i);159 }160 printf("\n");161 for (i = 0; i < len; ++i) {162 printf("%d ", a[i]);163 }164 printf("\n");165 166 // index = binarySearch(a, 10, 2);167 printf("%d binarySearch\n", binarySearch(a, len, key));168 printf("%d findLastLess\n", findLastLess(a, len, key));169 printf("%d findFirstGreaterEqual\n", findFirstGreaterEqual(a, len, key));170 printf("%d findLastLessEqual\n", findLastLessEqual(a, len, key));171 printf("%d findFirstGreater\n", findFirstGreater(a, len, key));172 printf("%d findFirstEqual\n", findFirstEqual(a, len, key));173 printf("%d findLastEqual\n", findLastEqual(a, len, key));174 }175 176 int main()177 {178 test();179 return 0;180 }
0 0
- 二分查找算法整理
- 二分查找整理
- 常用算法整理:二分查找
- 常用算法整理:二分查找
- 二分查找及其变形整理
- 查找问题整理(1)二分查找
- [整理]插入排序以及二分查找排序
- 【整理】二分查找及代码实现
- 算法整理-二分查找列表最大值
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- Set和Map数据结构
- leetCode---Subsets II
- 关于通过artTemplate模板的方式实现城市的联动
- Struts2获取表单数据
- java基础思维导图
- 二分查找整理
- 集线器与交换机的区别
- 源码简读之Gson解析
- 162. Find Peak Element 再做一遍!
- 解决junit @RunWith无法使用的问题
- 前端资源汇集
- 剑指offer-面试题65-滑动窗口的最大值
- DNS区域传输
- Git使用详细教程