二分查找

算法----二分查找

…衆ロ難τιáo~ 提交于 2019-12-14 02:34:13
public class aboutCas { public static int iG = 0; public static void main(String[] args) { int[] arr ={11,22,33,44,55,66}; //二分查找的前提是,数组必须是有序的。 int index = getIndex(arr,33); //定义一个整数,接收返回来的值 System.out.println(index); } public static int getIndex(int[] arr,int vule){ int min = 0; //定义最小值 int max = arr.length - 1; //定义最大值 int mid = (min + max) / 2; //定义中间值 while(arr[mid] != vule){ //判断传入的值是否等于中间值,如果不等于,往下执行 if(arr[mid] > vule){ //判断传入的值是否小于中间值 max = mid -1; //如果小于,则最大值为中间值的前面一位 }else if(arr[mid] < vule){ //如果大于中间值 min = mid +1; //最小值则改为中间值的后面一位 } mid = (min + max) / 2; if(min > max){ /

PTA——7-3 折半查找

纵饮孤独 提交于 2019-12-12 17:18:05
输入数组大小n,然后输入n(1<=n<=10)个整数,再输入查找值key,使用折半查找(二分查找)方法来判断数组中是否存在查找值key。 输入格式: 先输入数组大小n,然后输入数组的n个元素,最后输入待查找的值key。 输出格式: 如果数组中存在待查找的key,则输出Found,否则输出 Not exist。 输入样例: 在这里给出一组输入。例如: 4 12 89 32 91 32 输出样例: 在这里给出相应的输出。例如: Found # include <stdio.h> int main ( ) { int n , i , j , a [ 10 ] , temp ; int key , start , end , mid ; scanf ( "%d" , & n ) ; for ( i = 0 ; i < n ; i ++ ) { scanf ( "%d" , & a [ i ] ) ; } scanf ( "%d" , & key ) ; start = 0 ; end = n - 1 ; for ( i = 0 ; i < n - 1 ; i ++ ) { for ( j = 0 ; j < n - i - 1 ; j ++ ) { if ( a [ j ] > a [ j + 1 ] ) { temp = a [ j ] ; a [ j ] = a [ j + 1 ] ;

二分查找(上)(学习笔记)

Deadly 提交于 2019-12-11 20:36:11
有序数据集合的二分查找 定义 二分查找针对的是一个有序的数据集合。每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。 时间复杂度分析: 数据大小n,每次查找,缩小1/2 最多查找k次。n/2 k =1 k=O(logn) 应用场景 二分查找依赖顺序表结构(下标访问) 二分查找针对的是有序数据(不适用于排序变化的场景) 数据量太小不适合二分查找 数据量太大也不适合二分查找(需要连续内存) 二分查找的循环实现 let arr = [ ] //随机数组元素 for ( let i = 0 ; i < 40 ; i ++ ) { arr . push ( Math . round ( Math . random ( ) * 40 ) ) } //排序 arr . sort ( ( a , b ) => a - b ) console . log ( String ( arr ) ) //随机查找值 const value = Math . round ( Math . random ( ) * 40 ) console . log ( value , bsearch ( arr , value ) ) function bsearch ( arr , value ) { //指针low从左向右,指针high从右向左 let low

二分查找

ε祈祈猫儿з 提交于 2019-12-11 12:20:57
版本1 当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。 C++ 代码模板: 1 int bsearch_1(int l, int r) 2 { 3 while (l < r) 4 { 5 int mid = l + r >> 1; 6 if (check(mid)) r = mid; 7 else l = mid + 1; 8 } 9 return l; 10 } 版本2 当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。 C++ 代码模板: 1 int bsearch_2(int l, int r) 2 { 3 while (l < r) 4 { 5 int mid = l + r + 1 >> 1; 6 if (check(mid)) l = mid; 7 else r = mid - 1; 8 } 9 return l; 10 } 作者:yxc 链接:https://www.acwing.com/blog/content/31/ 来源:AcWing 来源: https://www.cnblogs.com/sxq-study/p/12021084

二分查找(上)

假如想象 提交于 2019-12-10 14:07:18
二分查找(上):如何用最省内存的方式实现快速查找功能? 1.无处不在的二分思想 2.O(logn) 惊人的查找速度 3.二分查找的递归与非递归实现 4.二分查找应用场景的局限性 1 二分查找依赖的是顺序表结构,简单点说就是数组; 2 二分查找针对的是有序数据; 3 数据量太小不适合二分查 4 数据量太大也不适合二分查找 5.总结 1.无处不在的二分思想 二分查找针对的是一个有序的数据集合,查找思想有点类似分治思想。每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。 2.O(logn) 惊人的查找速度 二分查找是目前为止遇到的第一个时间复杂度为 O(logn) 的算法。堆、二叉树的操作等等,它们的时间复杂度也是 O(logn)。这是一种极其高效的时间复杂度,有的时候甚至比时间复杂度是常量级 O(1) 的算法还要高效。 logn 是一个非常“恐怖”的数量级,即便 n 非常非常大,对应的 logn 也很小。比如 n 等于 2 的 32 次方,这个数很大了吧?大约是 42 亿。也就是说,如果我们在 42 亿个数据中用二分查找一个数据,最多需要比较 32 次。 3.二分查找的递归与非递归实现 最简单的情况就是有序数组中不存在重复元素: 非递归实现 public int bsearch ( int [ ] a , int n , int

违禁词过滤完整设计与优化(前缀匹配、二分查找)

浪尽此生 提交于 2019-12-10 06:12:40
可能不止在天朝,绝大多数网站都会需要违禁词过滤模块,用于对不雅言论进行屏蔽;所以这个应该算是网站的基础功能。大概在去年的时候我开发过这个功能,当时用6600+(词数)的违禁词库,过滤2000+(字数)的文章,耗时大概20ms左右,当时自我感觉还挺良好。过了这一段时间,回想一下,其实有不少地方可以做优化、可以总结;于是从头到尾捋了一遍。 原始需求: 违禁词最原始的需求,也是最直观的,即是查找一篇未知的文档中,是否包含了一个指定词语集合(违禁词库)中的词语。其实要实现这个功能的思路有许多,也可以很简单;但为了达到一定的效率,需要一些算法和数据结构的设计。 逻辑整理: 将原始的需求转换成可实现的逻辑,这里根据思维方向(出发点),可以有两个不同的选择:1. 遍历文档的每个词,查看违禁词库中是否包含这个词; 2. 遍历违禁词库中的每个词, 查看文档中是否包含这个词。 我这里采用的是第一种思维方向,原因有二: a. 我要过滤的文档的字数,大部分集中的2000~5000之间,少于违禁词的个数;遍历少的从性能上讲,有先天的优势。 b. 待过滤的文档是未知的,且变化的,而违禁词已知且固定;于是我们可对违禁词的数据结构做一定的设计,加快一个词在其中的查找,所以需要遍历的是文档(较主要的一个原因)。 思路有了,简单概括为:从文档中取词—>该词是否属于违禁词。 下一步我们需要整理出实现逻辑的步骤

经典算法系列之:二分查找

蓝咒 提交于 2019-12-09 13:44:21
1、前言 算法,在计算机中的地位,就相当于人类大脑的决策中枢系统,哪怕最简单的算法,其精妙的思维方式,都可以让人开启一扇新的视窗。 算法,它不仅仅只是狭义的用来解决计算机科学领域的问题,更是一种“思维方式”。算法思维,是一种深度思考和创造的过程。 算法,只有真正理解了,而不只是所谓的知道,并将应用到生活、工作、学习等各个方面,它将一定使人受益终生。 2、原理推导 二分查找 ,前提是在排好序的基础上,每次查找,将数据集合分成两个部分,取中间索引数值与被查找的数值比较,逐次缩小查找范围,直到找到数值。 给定一组 {1,2,3,4,5,6} 的原始有序数组,按照从小到大升序排列。 #step1 初始化低位索引为0,高位索引为数组长度减1索引为5,低位+高位除2,中间索引取整为:2=(0+5)/2,对应的数值就是数组中的3。 #step2 第一次比较,数值【5】大于【3】,所以低位索引被修为3=2+1,对应数组中的数值【4】,高位索引不变还是5,低位+高位除2,中间索引取整为:4=(3+5)/2,对应的数值就是数组中的【5】。 至此,二分查找已经完成,数值【5】在数组中的索引位置为: 4 ,在本次查找过程中,我们只用到两次查找就找到了被查找的数值,大大提高了查询效率。 3、代码示例 # 排序是前提,假设已经是有序数组 public int dichotomy(int array[],int

01-复杂度3 二分查找 (20分)

只愿长相守 提交于 2019-12-09 13:25:40
本题要求实现二分查找算法。 函数接口定义: Position BinarySearch( List L, ElementType X ); 其中 List 结构定义如下: typedef int Position; typedef struct LNode *List; struct LNode { ElementType Data[MAXSIZE]; Position Last; /* 保存线性表中最后一个元素的位置 */ }; L 是用户传入的一个线性表,其中 ElementType 元素可以通过>、==、<进行比较,并且题目保证传入的数据是递增有序的。函数 BinarySearch 要查找 X 在 Data 中的位置,即数组下标(注意:元素从下标1开始存储)。找到则返回下标,否则返回一个特殊的失败标记 NotFound 。 裁判测试程序样例: #include <stdio.h> #include <stdlib.h> #define MAXSIZE 10 #define NotFound 0 typedef int ElementType; typedef int Position; typedef struct LNode *List; struct LNode { ElementType Data[MAXSIZE]; Position Last; /*

二分查找

谁都会走 提交于 2019-12-07 20:38:31
Python 二分查找 二分搜索是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。 def binary_search(arr,l,r, x): if l < r: mid=int(l+(r-1)/2) if arr[mid]==x: return mid elif x<arr[mid]: return binary_search(arr,l,mid-1,x) elif x>arr[mid]: return binary_search(arr,mid+1,r,x) else: return -1 l=[-9,5,7,3,99,-59,4,6,59,-65] l.sort() print(l) x=binary_search(l,0,len(l),999) print(x) [-65, -59, -9, 3, 4, 5, 6, 7, 59, 99] -1 时间复杂度: 遍历方式,最优时间复杂度O(1),最坏O(n) 二分查找,2的logn次方等于n,最坏时间复杂度为O(logn),最优O(1) 来源: https:/

POJ3579 Median(二分查找)

对着背影说爱祢 提交于 2019-12-07 10:57:34
题目大意: 给出n(3<=n<=100000)个数,f(i,j)=|a[i]-a[j]| (1<=i小于j<=n)。求所有的f(i,j)里面中位数的值。 思路,二分查找中位数: # include<stdio.h> # include<stdlib.h> #include<algorithm> using namespace std ; int a[ 100000 ],o,n; int lily( int x, int y){ //二分 int r= 1 ,l=y,mid; while (r<l){ mid=(r+l)/ 2 ; if (a[mid]<x)r=mid+ 1 ; else l=mid; } return r; } int ok( int x){ int sum= 0 ; for ( int i= 1 ;i<=n;i++){ sum+=i-lily(a[i]-x,i); if (sum>=o) return 1 ; //如果大于则返回以 } return 0 ; } int main(){ int l,r; while ( scanf ( "%d" ,&n)> 0 ){ for ( int i= 1 ;i<=n;i++){ scanf ( "%d" ,&a[i]); //读入 } o=n*(n- 1 )/ 2 ; o=(o+ 1 )/ 2 ; sort(a+ 1 ,a