二分查找及其变形总结
2015-09-16 16:25
423 查看
题目:在一个已经排好序的数组中,查找关于key相关条件的下标。
#include <stdlib.h> #include <stdio.h> #include <assert.h> //0. 查找是否存在某个元素。说明:low是第一个元素下标;high是最后一个元素的下标 int originBinarySearch(int *arr, int low, int high, int key) { assert(arr!=NULL && low >= 0 && high - low >= 0); int mid = 0; while(low <= high){ mid = (low + high) / 2; if(arr[mid] == key){ //由于需要找和key相等的值,自然首先判断是否相同 return mid; }else if(arr[mid] < key){ //如果不相等,分两种情况:(1)小于key low = mid + 1; }else { //(2)大于key high = mid - 1; } } return -1; } //1. 查找第一次出现的位置(元素可能有重复) //注意返回left:如果找到就是第一次出现的位置;如果没找到就是第一个大于key的数 //(总结:返回的是不小于(>=,大于等于)key的最靠前数的下标) int bSearchFirstIndex(int* arr, int low, int high, int key) { assert(arr != NULL && low >= 0 && high - low >= 0); int mid, left = low, right = high; while(left <= right) { mid = (left + right) >> 1; if(arr[mid] >= key) right = mid - 1; //如果要求是返回大于key的第一个数的位置则将arr[mid] >= key修改为arr[mid] > key else left = mid + 1; } return left; } //要求返回大于key的第一个数的位置 int bSearchBigerIndex(int* arr, int low, int high, int key) { assert(arr != NULL && low >= 0 && high - low >= 0); int mid, left = low, right = high; while(left <= right) { printf("low:<%d>\tmid:<%d>\thigh:<%d>\n", low, mid, high); mid = (left + right) >> 1; if(arr[mid] > key) right = mid - 1; else left = mid + 1; } return left; } //2. 查找最后一次出现的位置(元素可能有重复) //注意返回right:如果找到就是第一次出现的位置;如果没找到就是第一个大于key的数 //(总结:返回的是不大于(<=,小于等于)key的最靠后数的下标) int bSearchLastIndex(int* arr, int low, int high, int key) { assert(arr != NULL && low >= 0 && high - low >= 0); int mid, left = low, right = high; while(left <= right) { mid = (left + right) >> 1; if(arr[mid] > key) right = mid - 1; //如果要求是返回小于key的第一个数的位置则将arr[mid] > key修改为arr[mid] >= key else left = mid + 1; } return right; } ////要求返回小于key的第一个数的位置 int bSearchSmallerIndex(int* arr, int low, int high, int key) { assert(arr != NULL && low >= 0 && high - low >= 0); int mid, left = low, right = high; while(left <= right) { mid = (left + right) >> 1; if(arr[mid] >= key) right = mid - 1; else left = mid + 1; } return right; }
//变形:在循环有序数组中查找指定元素。 int findInCircle( int * arr, int low , int high, int key) { int mid = 0; while(low<=high) { mid = low + (high - low) / 2; if (arr[mid] == key ) return mid; if(arr[mid]>=arr[low]) //前一部分为严格递增,后一部分为更小的循环递增数组 { if(arr[low] <= key && key < arr[mid]) high = mid -1; else low = mid +1; } else //后一部分为严格递增,前一部分为更小的循环递增数组 { if(arr[mid] < key && key <= arr[high]) low = mid + 1; else high = mid -1; } } return -1; }
本文参考了以下博客(向前辈学习,万分感谢!):
int63Ago博客:http://blog.csdn.net/int64ago/article/details/7425727
hackbuteer1博客:/article/1422718.html
相关文章推荐
- Monkey测试(一)
- Sql Server GetDate()和GetUTCDate()
- Windows与Linux文件系统互访的几种方法
- android .9图片的制作
- java多线程详解(7)-线程池的使用
- OpenCV获取文件夹下所有文件名
- 关于程序设计的内存分配问题
- 如何更改IE窗口初始大小及位置
- LeetCode274——H-Index
- Oracle数据库在线重做日志被删除的几种恢复方法
- Linux基础:目录结构(续)
- install ubandy-venv
- MySQL水平切分实现原理分析
- html5开发中td高度固定,超出部分隐藏无法实现的解决方案
- redis 学习
- 怎样让tomcat不自动生成JSESSIONID
- bind详解,主从DNS
- 深入讲解C++中的构造函数
- xUtils 中的BitmapUtils 全面注释
- Linux基础:目录结构