二分查找

浙大习题1.8 二分查找 (20分)

对着背影说爱祢 提交于 2020-02-28 01:37:47
习题1.8 二分查找 (20分) Position BinarySearch ( List L , ElementType X ) { int left = 1 , right = L - > Last ; int ans ; while ( left <= right ) { int mid = ( left + right ) / 2 ; if ( L - > Data [ mid ] == X ) { ans = mid ; return ans ; } else if ( L - > Data [ mid ] < X ) { left = mid + 1 ; } else if ( L - > Data [ mid ] > X ) { right = mid - 1 ; } } return NotFound ; } 很简单的二分查找,因为是顺序存储的数组,直接初始设l为0,r为L->Last即数组的最后一个,比较mid与需要查找值的大小,如果mid大于需要查找值,r=mid-1,否则l=mid+1。直到比较到相同的值为止。如果找不到返回NotFound。 来源: CSDN 作者: 快乐风男hasaki 链接: https://blog.csdn.net/qq_45472201/article/details/104543079

lower_bound( )和upper_bound( )

泄露秘密 提交于 2020-02-27 13:33:14
lower_bound( )和upper_bound( )适用于 有序序列 ,因为内部是用的二分查找,所以必须得是有序的。 它第一个参数与第二个参数是与sort一样的,也是用来确定区间范围的(闭区间) 参数: first 寻址要搜索的范围中的第一个元素的位置的向前迭代器。 last 寻址要搜索的范围中最后一个元素的下一位置的向前迭代器。 value 在排序范围中搜索的处于第一个位置或可能处于第一个位置的值。 cmp 用户定义的谓词函数对象定义一个元素小于另一个。二进制谓词采用两个参数,并且在满足时返回 true,在未满足时返回 false。 返回值: 向前迭代器在有序的范围内(具有大于或等于指定值的值)的第一个元素的位置,其中等效性由二进制谓词指定。 在升序的数组中 lower_bound( begin,end,num):二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。 upper_bound( begin,end,num):二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。 在降序的数组中,我们使用第四个参数greater,重载lower_bound()和upper_bound() lower

PAT A1043

你离开我真会死。 提交于 2020-02-27 03:04:28
目录 疑问 代码 反思 疑问 暂无 代码 //二分查找树 //需要注意的是,二分查找树的先序遍历序列,应该能重新构建这棵二分查找树 # include <cstdio> struct node { int data ; node * lchild ; node * rchild ; } ; const int maxn = 1010 ; int input [ maxn ] ; //前序数组 int pre [ maxn ] ; int m = 0 ; //后序数组 int post [ maxn ] ; int p = 0 ; node * newNode ( int v ) { node * root = new node ; root - > data = v ; root - > lchild = NULL ; root - > rchild = NULL ; return root ; } void insert ( node * & root , int x ) { if ( root == NULL ) { root = newNode ( x ) ; } else if ( x < root - > data ) { insert ( root - > lchild , x ) ; } else if ( x >= root - > data ) { insert

二分查找(数据结构)

馋奶兔 提交于 2020-02-26 22:25:29
https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-suan-fa-xi-jie-xiang-jie-by-labula/ 这二分查找的所有细节都覆盖了写的太好了。。。。 来源: CSDN 作者: 菁姐的后台 链接: https://blog.csdn.net/qq_37668436/article/details/104523343

二分查找--34. 在排序数组中查找元素的第一个和最后一个位置

不羁岁月 提交于 2020-02-26 13:19:51
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 你的算法时间复杂度必须是 O(log n) 级别。 如果数组中不存在目标值,返回 [-1, -1]。 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4] 代码实现 class Solution { public: int left_index(vector<int>& nums,int target) { int begin = 0; int end = nums.size() - 1; while(begin <= end) { int mid = (begin + end) / 2; if(nums[mid] == target) { if(mid == 0 || nums[mid - 1] < target) { return mid; } end = mid - 1; } else if(target < nums[mid]) { end = mid - 1; } else if(target > nums[mid]) { begin = mid + 1; } } return -1; } int right_index(vector<int>& nums,int target) { int begin

算法之二分查找(上)

送分小仙女□ 提交于 2020-02-26 09:44:29
文章来源: http://blog.seclibs.com/算法之二分查找上/ 二分查找在平时的生活中也挺常用的,比如说以前玩的猜数游戏,每次都取中间数,然后得知是大了,还是小了,这个例子也就是二分查找。 比如下面的这个例子,要查找有没有数值19,其中low和high是查找的区间的下标,mid是查找区域的中间值的下标。 二分查找的思想是比较容易理解的,而且它的时间复杂度也是比较低的。假设数据大小为n,每次查找完后都会缩小一半,即为除以2,最坏的情况也就是一直到查找空间为空的时候,所以它们的变化为n,n/2,n/4,n/8,…,n/2k,当n/2k=1时,k即为缩小的次数,因为每次都只涉及到两个数的大小比较,所以k次操作的时间复杂度为O(k),又因为n/2k=1,所以k=log2n,时间复杂度也就是O(logn),这是一个非常恐怖的数量级了,比如n为2的32次方,大约是四十多亿,用二分查找来查找里面的一个数的话,最多比较32次也就可以得到这个值了,这是一个非常恐怖的情况。 上面的原理已经很明确了,所以二分查找的实现并不是很复杂,但是有一个前提条件,有序数组中不存在重复元素,只有在这个情况下,二分查找的实现才是相对简单的,具体的实现在下一篇文章里提及。 虽然二分查找时间复杂度低,查找起来非常高效,但它也有一定的适用条件的。 首先,二分查找是依赖于数组的,如果使用其他的数据结构来实现的话

【从0到1学算法】大O表示法

偶尔善良 提交于 2020-02-26 03:36:50
一般我们在选择算法时,都是想要选择效率最高的算法。那算法的效率,用什么表示?没错!就是用大O表示法。 PS : 大O表示法中,log即为log2,后面不再说明。 下面以简单查找和二分查找,在含有n个元素的有序列表中查找其中一个元素为例,下表总结了我们发现的情况。 使用简单查找时,最多需要猜测次数与列表长度相同,这被称为线性时间,大O表示法为O(n)。 二分查找则不同,最多需要猜测次数为logn(n为列表长度),这被称为对数时间(log时间),大O表示法为O(logn)。 基本概念 大O表示法指出了算法的速度有多快。 可能你会好奇,它的单位是多少?秒?没有单位,它并非指的是时间,而是从增量的角度衡量。 列表中查找元素,简单查找、二分查找的增速如下图。 假若我们不知道增速,只知道查找100个元素时的查找时间,猜测10000个元素时的查找时间: 对于简单查找,100个元素时为100毫秒,简单推算出10000个元素为10秒; 对于二分查找,100个元素时为7毫秒,简单推算出10000个元素为700毫秒。 PS:简单推算 10000个元素时的运行时间= 运行时间(100个元素时)* 100 简单查找的推算是对的,因为的增速是n,而二分查找的推算是错的,它的增速为logn,这便不能理所当然简单推算了。 很显然,我们只要知道算法的增速,便能知道它在n个元素中运行的运行时间了

二分查找和线性查找(二)

别等时光非礼了梦想. 提交于 2020-02-25 12:32:34
二分查找和线性查找可运用于数组 线性查找 时间复杂度 O(n) 1、遍历数组 2、拿目标和数组中的元素进行匹对 3、找到则返回数组中该元素的下标 4、未查询到则返回-1 //自定义数组 public class MyArray { int[] elements; // 线性查找 public int search(int target) { for (int i = 0; i < elements.length; i++) { if (target == elements[i]) { return i; } } // 如果没找到 return -1; }} 二分查找 时间复杂度 O(log2n) 二分查找是有必要的前提,即数组中的元素一定要排好顺序 1、找到该数组的中点 2、目标元素与中点值进行比对 相等则返回该中点元素下标 如果目标元素大于中点 则把低位元素的下标设置成中点向右移动一位 如果目标元素小于中点 则把高位元素的下标设置成中点向左移动一位 根据低位元素下标和高位元素下标重新计算出中点 public class MyArray { int[] elements; // 二分查找 public int binarySearch(int target) { int low = 0; int high = elements.length - 1; int mid = (low

二分查找

随声附和 提交于 2020-02-25 02:31:39
/* 先定数组长度,无法获取一个Int数组的真实长度 如 int a[20]={1,2} 实际长度是多少呢? sizeof(a)/sizeof(a[0])是算不出来的!只能自己写函数了! 注意,二分查找是查找一个有序的序列,这里的演示的有序,有两种 1、bindSearch函数自身提供的数组(索引器)的下标有序,废话,数组本来就有序。 2、被查找的数据的索引也要有序,什么意思?看一个json结构 [ { id:1,name:mike }, { id:2,name:rock }, ] 所以这里的id必须排序 */ void bindSearch() { /* low ---- mid------higt */ int low = 0, higt, mid = 0, len, a[] = { 1,3,4,12,13,15 }, key=1; len = sizeof(a) / sizeof(a[0]) - 1; higt = len-1; if (len <= 0) { printf("折半查找!至少两个数据嘛!\n", len, mid); return; } while (low <= higt) { mid = (low + higt) / 2 ; printf("当前数组长度=>%d,mid=>%d\n", len, mid); if ( a[mid] == key ) {

二分查找算法-Java

本小妞迷上赌 提交于 2020-02-22 23:26:06
/** * @author cnkeysky */ public class DemoTest { public static void main ( String [ ] args ) { int [ ] arr = { 1 , 3 , 10 , 17 , 20 } ; int index = binarySearch ( arr , 3 ) ; if ( index < 0 ) { System . out . println ( "未查找到该数" ) ; } else { System . out . println ( "该数在数组中的下标为: " + index ) ; } } public static int binarySearch ( int [ ] arr , int value ) { int len = arr . length ; return binarySearch ( arr , value , 0 , len - 1 ) ; } public static int binarySearch ( int [ ] arr , int value , int left , int right ) { if ( left > right ) { return - 1 ; } int mid = ( right + left ) / 2 ; if ( arr