秒懂如何运用二分查找算法
上篇我们讲解了八种排序算法的原理,本文再深度剖析如何运用二分查找算法。一、二分查找的实现
对于给定的已经有序的数列,我们需要在该数列中查找是否存在某个元素。
每次都与数列最中间的元素进行比较,可以缩小一半的查找区间,直至找到目标元素或者区间被缩小为0,元素不存在。比如下面的数列中,我们想要查找元素19,那么大致的过程就是这样的:
二分查找过程示意图
使用代码实现如下: public static void main(String[] args) { int[] data = {8, 11, 19, 23, 27, 33, 45, 55, 67, 98}; int result = binarySearch(data, data.length, 19); log.info("查找元素19的位置是:{}", result); } public static int binarySearch(int[] data, int size, int target) { int low = 0; int high = size - 1; while (low <= high) { int middle = (low + high) / 2; if (data[middle] == target) { return middle; } else if (data[middle] < target) { low = middle + 1; } else { high = middle - 1; } } log.info("元素{}查找不存在!", target); return -1; }
二分查找的时间复杂度是O(logn),对数阶时间复杂度的算法效率非常高。 二、二分查找的特点及使用场景
二分查找必须依赖以下条件才能发挥作用: 数据结构一定要是顺序表,比如数组。如果是不支持随机访问的数据结构,那么二分查找就无法使用; 待查找的数列一定要是有序的。如果给定的数列是无序的,那么我们就必须先使用排序算法将数列进行排序,否则也无法使用二分查找; 不适合频繁插入和删除的数列;因为数列需要保持有序,要么在插入和删除的时候保证有序,要么在插入数列后使用排序算法进行排序,这些都是时间开销; 不适合数据量太小的数列;数列太小,直接顺序遍历说不定更快,也更简单;但是有一种场景除外,就是每次元素与元素的比较是比较耗时的,这个比较操作耗时占整个遍历算法时间的大部分,那么使用二分查找就能有效减少元素比较的次数,从而节约时间; 不适合数据量太大的数列;二分查找作用的数据结构是顺序表,也就是数组,数组是需要连续的内存空间的,系统并不一定有这么大的连续内存空间可以使用; 三、二分查找相关的变体
查找第一个等于给定值的元素 public static void main(String[] args) { int[] data = {8, 11, 19, 19, 19, 33, 45, 55, 67, 98}; int result = binarySearch1(data, data.length, 19); log.info("查找元素19的位置是:{}", result); } public static int binarySearch1(int[] data, int size, int target) { int low = 0; int high = size - 1; while(low <= high){ int middle = (low + high) / 2; if(data[middle] > target){ high = middle - 1; } else if(data[middle] < target){ low = middle + 1; } else { // 当前元素等于目标元素,但是不一定是第一个等于目标元素的 if((middle == 0) || (data[middle-1] != target)){ // 说明当前middle是第一个等于目标元素的 return middle; } else { // 继续在middle的前半区间进行查找 high = middle - 1; } } } return -1; }
查找最后一个等于给定值的元素 else { // 当前元素等于目标元素,但是不一定是最后一个等于目标元素的 if((middle == size-1) || (data[middle+1] != target)){ // 说明当前middle是最后一个等于目标元素的 return middle; } else { // 继续在middle的后半区间进行查找 low = middle + 1; } }
查找第一个大于等于给定值的元素 public static int binarySearch3(int[] data, int size, int target) { int low = 0; int high = size - 1; while(low <= high){ int middle = (low + high) / 2; if(data[middle] >= target){ if(middle == 0 || data[middle-1] < target){ // 是第一个大于等于target的位置 return middle; } else { // 继续往middle的前半部分去找 high = middle - 1; } } else { // 继续往middle的后半部分去找 low = middle + 1; } } return -1; }
查找最后一个小于等于给定值的元素 public static int binarySearch4(int[] data, int size, int target) { int low = 0; int high = size - 1; while(low <= high){ int middle = (low + high) / 2; if(data[middle] <= target){ if(middle == (size-1) || data[middle+1] > target){ return middle; } else { low = middle + 1; } } else { high = middle - 1; } } return -1; }四、总结
在实际的查找业务场景中,凡是可以使用二分查找的问题都可以使用散列表和二叉查找树来完成,而且后面两者的使用频率要更高。
什么情况下才使用二分查找呢?用于求解近似查找的问题上,比如上面描述的四种二分查找变体问题,而这类问题使用散列表、二叉查找树或者别的数据结构和算法就不太好实现。
为什么国家允许生三胎,大家却不愿意生二胎三胎了?为什么国家允许生三胎!大家却不愿意生二胎三胎,据我们观察主要原因是生活压力太大。现代人的生活节奏非常快,年轻人要忙着上班赚钱,根本就没有太多时间来照顾孩子,不过抛开这却不是最根本的
科学研究表明06岁是孩子语言发育的敏感期儿语很多家长尤其是女性在孩子开始学习说话时,往往喜欢和习惯使用儿语。因为儿语具有较高水平的音韵,且具有多样化和夸大的音调语速缓慢地使用重复话语把一些词汇重叠和相近音并列语意简单等特
专家表示,旅行对您的健康有这5种好处春日生活打卡季我们不需要坐在这里告诉你显而易见的事情我们都知道现在是我们生活的压力时期。但我们需要与你分享的是,至少有一个解决方案可以减轻一点压力那种情感上的分量去旅行,即使是去一
北京周边民宿丨隐藏在山谷中的浪漫小众私汤民宿落絮游丝三月候,风吹雨洗一城花。未知东郭清明酒,何事西窗谷雨茶。不知不觉谷雨就悄然而至。谷雨是春天最后一个节气。谷雨过后,夏已始,天气渐渐转暖,可今年与往年不同,乃是微凉。我独自漫
中国首个国家公园,是美国黄石国家公园的13倍,究竟藏着什么秘密国家公园不仅是森林及河流的源泉,更是生命的源泉。许多国家都拥有自己的国家公园,像美国的黄石国家公园。美国的黄石国家公园加拿大的班夫国家公园这些都代表着,这个国家最震撼最特别最优美最
从高速公路发展看百年变化文陈玲图崔方平京新高速无人区段自退休后,我萌生了世界这么大,我要去看看的念头,爱上了旅游,曾屡次自驾出游,与高速公路结下了不解之缘,亲身体验感受到了我们国家,在交通建设特别是高速公
北京周边游四个必打卡地周末时间出游(上)在北京快两年了,平时工作的压力,导致周末总想出去散散心。相比于市内的景点,我更愿意去郊区周边走一走,看看草的绿,视野的辽阔。没有高楼大厦带来的压迫感,城市的喧嚣,就这样呆上两天,带
中国最具人气的8条小吃街榜单,历史最长的有1300年,你都去过吗人在路途,一生要走过无数的城市,去感受不同的风土人情,每当回忆起去过的这些地方,最难忘的除了风景,一定还有品尝过的那道道美食。小编旅行二十年,走过无数的城市,最难忘的还是下面这8条
中国颜值高的4座城市,环境非常优美,游客不想离开虽然在日常的生活中,很多人会利用颜值来评价一个人的长相,但是我们发现颜值其实可以评价众多的事物,比如像城市的标准。要说城市的标准,可以从政治,面貌,经济等等特色来决定。下面就给大家
国内首个海军公园,一玩一整天!LOOK!QINGDAO西海岸文旅发布春天逛公园是正经事在西海岸新区古镇口核心区藏着我国首个海军主题公园航拍镜头下的它美如七彩调色盘不仅好看好玩好拍还能涨知识这个春天遛娃安排上吧!
孩子到底几岁上幼儿园合适?孩子到底几岁上幼儿园合适?有的家长在孩子不到两周就去早教,有的两周多去幼儿园,还有的三周多去幼儿园!先听听专家的意见孩子生长到三周岁大的时候,这个年龄段,非常适合上幼儿园,但是,孩