查找算法

【算法•日更•第一期】查找算法:简单实现二分

旧巷老猫 提交于 2019-12-30 22:40:17
▎二分 ☞ 『算法思想』   二分也就是 二分查找 ,又叫 折半查找 。这种算法正如其名,每一次都要分一半。废话不多说,直接抛砖引玉: Q:现在来思考一个问题:在一千以内我已经心中想好了一个数(不耍赖),你可以随意询问我一个数,我只会说大了、小了和猜对了,想必你一定玩过,那么请问怎样询问才能使用次数最少?   Answer:   其实有常识的人都知道,第一次说500;第二次说(第一次大了)250或(第一次小了)750;第三次125、375、625或875……以此类推。每一次都要砍一半询问,这样无疑不需要每个数都被查找一遍。如果你这样干过,那么可以说你已经会了二分的思想了。可能我没有说清楚,那么就再举个例子吧:(我心里想着666) A:500? B:小了 A:750? B:大了 A:625? B:小了 A:687? B:大了 A:656? B:小了 A:671? B:大了 A:663? B:小了 A:667? B:大了 A:665? B:小了 A:666? B:猜对了 ☞ 『算法复杂度分析』   由于每一次都会分掉一半,因此时间复杂度就是O(log n)。   形象一些说明就是最多查找n以2为底数的 对数 次。    对数 : 在数学中,对数是对求幂的逆运算,正如除法是乘法的倒数,反之亦然。 (copy自百度)比如说n=1024,log 1024= 10 ,因为2 10 =1024。

<查找算法> 二分查找BinarySearch

廉价感情. 提交于 2019-12-30 22:39:48
1 #include<iostream> 2 using namespace std; 3 4 int BinarySearch(int arr[],int begin,int end,int num) 5 { 6 if(arr == NULL || begin < 0 || end < 0 || begin >= end) return -1; 7 8 int mid = (begin+end)/2; 9 if(arr[mid] == num) 10 return mid; 11 else if(arr[mid] > num) 12 BinarySearch(arr,begin,mid-1,num); 13 else if(arr[mid] < num) 14 BinarySearch(arr,mid+1,end,num); 15 } 16 17 int main() 18 { 19 int arr[] = {2,4,11,13,20,24,33,56,78,91}; 20 cout << "找到num在数组中的下标为:" << BinarySearch(arr,0,sizeof(arr)/sizeof(arr[0])-1,78); 21 22 system("pause"); 23 return 0; 24 } 来源: https://www.cnblogs.com

关于树,各种平衡树查找树的资料合集~~

我怕爱的太早我们不能终老 提交于 2019-12-30 05:40:37
我们知道,对于一般的二叉搜索树(Binary Search Tree) ,其期望高度(即为一棵平衡树时)为log2n,其各操作的时间复杂度(O(log2n))同时也由此而决定。 但是,在某些极端的情况下(如在插入的序列是有序的时) ,二叉搜索树将退化成近似链或链,此时,其操作的时间复杂度将退化成线性的,即O(n) 。我们可以通过 随机化 建立二叉搜索树来尽量的避免这种情况,但是在进行了多次的操作之后,由于在删除时,我们总是选择将待删除节点的后继代替它本身,这样就会造成总是右边的节点数目减少,以至于树向左偏沉。这同时也会造成树的平衡性受到破坏,提高它的操作的 时间复杂度 。 平衡二叉搜索树 (Balanced Binary Tree)具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。常用算法有红黑树、AVL、Treap、伸展树等。在平衡二叉搜索树中,我们可以看到,其高度一般都良好地维持在O(log2n),大大降低了操作的时间复杂度。 BST Binary Search Tree~ 二叉搜索树 ( Binary Search Tree ),或者是一棵空树,或者是具有下列性质的 二叉树 : 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左

java基础 二分查找算法

邮差的信 提交于 2019-12-30 03:44:30
/* * 折半查找法: * 思路: * 定义三个变量记录查找范围中最大、最小和中间的索引值,每次都是使用中间索引值与要查找的目标进行对比,如果不符合,那么就不停缩小查找范围 * */ //前提:查找的序列必须是有序的 int[] arr1 = {3,5,7,10,22,45,191}; //定义三个变量记录查找的边界和中间位置,并且初始化 int min = 0; int max = arr1.length; int mid = (min + max)/2; //定义一个变量,记录要查找的元素值; int target = 56; while(true){ if(target>arr1[mid]){ min = mid+1; }else if(target<arr1[mid]){ max = mid-1; }else if(target==arr1[mid]){ System.out.println("找到了" + target + "的位置是:" + mid); break; } mid = (max+min)/2; if(max<min){ System.out.println("没找到,查找的元素不存在"); break; } } 来源: https://www.cnblogs.com/michaellin/p/6219197.html

查找算法

丶灬走出姿态 提交于 2019-12-30 01:05:23
目前不断更新中,算法描述图有时间补上 //查找使用ASL平均查找长度来判断算法的性能 ASL=ΣPiCi (i∈[1,n]) //线性表的查找 template<class T> class Search { public: //顺序查找: //条件: 无 //思想:从后往前与要查找的值比较,设置一个哨兵简化算法 //查找成功的情况下 平均查找长度ASL=(n+1)n/2n=(n+1)/2 //查找不成功ASL=n+1 int SeqSearch(T a[],int n,T key){ int i; a[0] = key; //设置哨兵,如果返回的值为0的话说明查找失败 for ( i = n; a[i] != key; i--); return i; } //折半查找: //条件: 关键码有序 //思想:设置变量low,high分别指向最高和最低值,令mid=(high+low)/2,将mid与key比较,可以根据大小判断位于哪个区域,逐渐缩小 //以十个元素为例,查找第5个元素需要比较1次,第2、8元素需要2次,1、3,6,9需要3次,4、7需要4次,可以将其看为一个完全二叉树,称为判定树 //那么深度与判定树的深度相同 //查找成功 Σj*2^(j-1)/n [1,h] (Σ2^t [1,h] <= n) 当n>50 ASL≈log2(n+1) - 1 //查找失败 ASL

博客作业05—查找

孤者浪人 提交于 2019-12-30 00:52:52
一:学习总结 1查找结构思维导图 2、查找学习体会 查找这一章,主要介绍的是如何在某种数据结构中找出给定条件的元素。 不同的数据结构中需要不同的算法,我们学习了线性表,数表,和哈希表 的查找。并且学会了在相同数据结构下减少时间复杂度的方法和思想。 二:PTA实验作业 题目1:是否是二叉搜索树 1设计思路 bool IsBST( BinTree T ) { 若T是空树则是二叉搜索树; 中序遍历该树得到的新节点的值一定要大于前一个值,否则不是; 返回真; } 一开始只考虑了左右子树都是二叉搜索树的情况, 但有可能不是这种情况 题目2:二叉搜索树中的最近公共祖先 1设计思路 int LCA( Tree T, int u, int v )//寻找u,v的共同祖先 { 若树为空或者u或v不在该树中 ERROR; 若u或者v就是根节点的值 return T->Key; 若u或者v在同一棵子树上 return T->Key; 若u大于T->key 最近共同祖先在左子树上; 若u大于T->key 最近共同祖先在右子树上; } int find(Tree T,int u)//查看u是否在树中 { 若树为空:则返回0;//不在 查找该树: 若找到等值的key,则u在该树中; 否则不在; } 2代码截图 部分正确:没有考虑到当前节点就是树的公共祖先 和关键字不在书中的情况。 部分正确:无error的输出

博客作业05—查找

那年仲夏 提交于 2019-12-30 00:52:39
1.学习总结(2分) 1.1查找的思维导图 2、查找学习体会 不同的数据结构中需要不同的算法,其中线性表查找算法较为简单,树表的知识点较多,容易遗忘,需要时常复习,哈希表主要分析平均查找长度。 2.PTA实验作业(4分) 题目1:是否是二叉搜索树 1、设计思路 如果T是空树,则为二叉搜索树,返回真;如果为非空若左右孩子都为空,是线索二叉树;非空右子树的所有键值大于其根结点的键值,非空左子树的所有键值小于其根结点的键值; 2、代码截图 3、PTA提交列表说明 2.1 题目2:6-3 二叉搜索树中的最近公共祖先 2.2 设计思路 1 一种情况为u,v都不在二叉树中   2一种情况为u,v在二叉树中 (1)u,v都在左子树上,T=T->Left,递归,求出公共祖先。 ( 2 ) u , v都在右子树上,T=T->Right,递归,求出公共祖先。 (3)u,v分别在左子树和右子树上,公共祖先就为当前节点指向的key 4)u,v有一个在根上,公共祖先就为在根上的那个。 2.3 代码截图 3、PTA提交列表说明 2.1 题目1:7-1 QQ帐户的申请与登陆 2.2 设计思路 使用map完成算法要求。 1.若输入L,使用map查找此帐号是否已经存在且密码是否正确。 2.否则进行新建帐号,储存输入的账号与密码。 2.3 代码截图 三:截图本周题目集的PTA最后排名 1 PTA排名: 四:阅读代码

二分查找(下):如何快速定位IP对应的省份地址?

烂漫一生 提交于 2019-12-29 22:50:37
二分查找(下):如何快速定位IP对应的省份地址? 在百度,在搜索框中随机输一个IP地址,可以看到它的归属地,这是通过维护一个很大的IP地址库来实现的,在庞大的地址库中逐一对比IP地址所在的区间,非常耗时,假设我们有12W这样的IP区间与归属地的对应关系,如何快速定位出一个IP地址的归属地? 四个常见的二分查找变形问题 查找第一个值等于给定值的元素 查找最后一个值等于给定值的元素 查找第一个大于等于给定值的元素 查找最后一个小于等于给定值的元素 查找第一个值等于给定值的元素 有序数据集合中存在重复的数据,希望找到第一个值等于给定值的数据 有一个有序数组,a[5],a[6],a[7]=8,希望查找第一个等于8的数据,即下标为5的元素 public int bsearch(int[] a ,int n,int value){ int low = 0; int high = n -1 ; while(low <= high){ int mid = low + ((high - low)>>1); if(a[mid] >= value){ high = mid - 1; }else{ low = mid - 1; } } if(low < n && a[low]==value) return low; else return -1; } 该方式不好理解,换一种实现方法: public int

散列表的查找技术

你。 提交于 2019-12-29 14:51:09
散列函数的构造 直接定址法 除留余数法 数字分析法 平方取中法 折叠法(分段叠加法) 冲突处理方法 开放定址法 链地址法 建立公共溢出区 散列表 :采用散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间称为散列表。 散列函数 :将关键码映射为散列表中适当存储位置的函数。 散列地址 :由散列函数所得的存储位置址 。 散列技术的关键问题: ⑴ 散列函数的设计。如何设计一个简单、均匀、存储利用率高的散列函数。 ⑵ 冲突的处理。如何采取合适的处理冲突方法来解决冲突。 散列函数 直接定址法 除留余数法 数字分析法 平方取中 折叠法 冲突的 处理 开散列方法( open hashing,也称为拉链法,separate chaining ,链地址法) 闭散列方法( closed hashing,也称为开地址方法,open addressing ,开放定址法) 建立公共溢出区 线性探测法散列表 假设给定的值为K,根据所设定的散列函数h,计算出散列地址h (K) 否则将该地址中的值与K比较,若相等则检索成功,算法结束 否则,按建表时设定的处理冲突方法查找探查序列的下一个地址,如此反复下去 直到某个地址空间未被占用(查找不成功,可以插入),算法结束 或者关键码比较相等(有重复记录,不需要插入)为止,算法结束 如果探测完整个hash表,都没有进行插入或查找失败,则抛出空间异常

控制反转(IoC)与依赖注入(DI)

风流意气都作罢 提交于 2019-12-29 14:45:57
1. 控制反转 (Inversion of Control) 与依赖注入 (Dependency Injection) 控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。 IoC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:<1>依赖查找(Dependency Lookup): 容器 提供回调接口和上下文环境给 组件 。EJB和Apache Avalon都使用这种方式。<2>依赖注入(Dependency Injection):组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。后者是时下最流行的IoC类型,其又有接口注入(Interface Injection),设值注入(Setter Injection)和构造子注入(Constructor Injection)三种方式。 图1 控制反转概念结构 依赖注入之所以更流行是因为它是一种更可取的方式:让容器全权负责依赖查询,受管组件只需要暴露JavaBean的setter方法或者带参数的构造子或者接口,使容器可以在初始化时组装 对象 的依赖关系。其与依赖查找方式相比,主要优势为:<1>查找定位操作与应用代码完全无关。<2