查找算法

二分查找

烈酒焚心 提交于 2019-12-01 10:35:09
概念介绍   有同学想了解二分查找,今天它来了!二分查找也叫折半查找,查找效率较高。但是它有一个 使用前提:待查找的序列必须为有序的,升序或降序都可以 。我们来看一下它的核心思想:假设有n个元素的序列升序排列,以中间值arr[n/2]将序列分为两部分,我们取序列的中间值arr[n/2]与待查找数x比较,如果x<arr[n/2],就在序列的左半部分继续进行二分查找,如果x>arr[n/2],就在序列的左半部分继续进行二分查找,退出二分查找的条件为x=arr[n/2]。概念总是太抽象,咱们举例子来说明。   需求:在arr=[1,3,5,7,9,10,13,18]中,找到5。   第一轮查找:中间值为arr[(起始值下标:0+末位置下标:arr.length-1)/2]=arr[(0+8-1)/2]=arr[3],因为5<7,在第一轮中间值左半部分查找,也就是[ 1,3,5, 7 ,9,10,13,18](红色序列元素中查找)。   第二轮查找:找第二轮中间值arr[(起始值下标:0+第一轮中间值下标-1)/2]=arr[(0+3-1)/2]=3,3<5,在第二轮中间值右半部分查找,也就是[1,3, 5 ,7,9,10,13,18](红色序列元素中查找)。   第三轮查找:找第三轮中间值arr[(起始值下标:第二轮中间值下标+1+结束下标:第一轮中间值下标-1)/2]=arr[(2+3

算法第二章总结

牧云@^-^@ 提交于 2019-12-01 08:59:40
  对分治的学习与理解:   分治,字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。 分治算法可以分三步走:分解 -> 解决 -> 合并 分解原问题为结构相同的子问题。 分解到某个容易求解的边界之后,进行递归求解。 将子问题的解合并成原问题的解。   对二分的学习与理解:   二分搜索,也称折半搜索、二分查找,是用来在一个有序数组中查找某一元素的算法。它每次考察数组当前部分的中间元素,如果中间元素刚好是要找的,就结束搜索过程;如果中间元素小于所查找的值,那么左侧的只会更小,不会有所查找的元素,只需要到右侧去找就好了;如果中间元素大于所查找的值,同理,右侧的只会更大而不会有所查找的元素,所以只需要到左侧去找。相对于顺序搜索,二分搜索会在每次查找时把区间减半,也不需要遍历每一个数,最多需要logN次查找,在竞赛中也时常会用到。   结对编程情况汇报:   合作愉快,代码也慢慢的规范起来,在打题时代码也开始慢慢的变得容易维护起来。对于自己的见解也能很好的提出并互补,期待下一章的上机。    来源: https://www.cnblogs.com/jjmmboom/p/11674673.html

线性查找

若如初见. 提交于 2019-12-01 08:59:36
概念介绍   有同学想了解线性查找,今天它来了!线性查找是一种最简单的查找方法,看一看它的核心思想,凭什么说它最简单。 核心思想:给出一组序列,从头开始逐一对比,找到目标值则返回 。简单的说,就是遍历并逐一对比。不管再简单,也要举个例子。   需求:在序列arr=[2, 7, -5, 30, 9]中找到-5。   从数组头结点开始,arr[0]=2,!=-5,找下一个元素。   arr[1]=7,!=-5,找下一个元素。   arr[2]=-5,找到目标元素,返回即可。 代码实现   遍历+逐个比对,找到目标值。 1 public static int seqSearch(int[] arr, int value) { 2 for (int i = 0; i < arr.length; i++) { 3 if (arr[i] == value) { 4 return i; 5 } 6 } 7 return -1; 8 }   至此,代码编写完成,Git地址:https://github.com/HollowCup/algorithms-and-data-structure,具体实现位于algorithm工程下的search目录SeqSearch,如果发现不足之处,请联系我进行更改,十分感谢!关注我,为你揭秘更多查找算法! 来源: https://www.cnblogs.com

算法 在连续线性空间里查找

时间秒杀一切 提交于 2019-12-01 08:55:25
算法 在连续线性空间里查找 查找可以分成:有序和无序查找 无序查找 顺序比较 缺点:效率低下 //e为查找的对象,lo和hi是要查找的区间 template <typename T> Rank Vector<T>::find(T const & e, Rank lo, Rank hi){ while(hi != lo && _elem[hi-1] != e){ hi--; } return hi - 1; } 有序查找 原理:找个某个点,根据这个点切分成2个区间。 1,二分查找(binary search) 这个点是:中间点 优点:简单,最坏情况的效率也不低 缺点:如果要查找的值在中间点的右侧就比在左侧多一次比较 //二分查找算法:在有序向量的区间[lo, hi)内查找元素e,0 <= lo <= hi <= _size template<typename T> Rank Vector<T>::search ( T const& e, Rank lo, Rank hi ) const { while ( lo < hi ) { //每步迭代仅需做一次比较判断,有两个分支 Rank mi = ( lo + hi ) >> 1; //以中点为轴点(区间宽度的折半,等效于宽度之数值表示的右移) ( e < _elem[mi] ) ? hi = mi : lo = mi + 1; /

查找链表的中间结点

夙愿已清 提交于 2019-12-01 08:36:31
查找链表的中间结点 题目:设计一算法查找链表的中间结点。要求该算法的时间复杂度为O(n),空间复杂度为O(1)。 当看到这个时候想了半天没想出来,时间复杂度是没问题的,但是空间复杂度要达到O(1)还是有一点不好办,然后百度了一下,发现有快指针和慢指针的写法,于是我就进去瞧了瞧,突然惊叹一声“妙啊!” 使用两个指针同时遍历链表,快指针遍历的速度是慢指针的两倍,那么当快指针遍历完整个链表的时候,慢指针恰好位于整个链表的中间部分,那么此刻输出 slow->data 即为链表中间的元素 代码: // Created by CAD on 2019/10/14. #include <bits/stdc++.h> using namespace std; struct Node{ int data; Node* next; Node(){next=NULL;} }; typedef Node* LinkList; int get_mid(LinkList L) { LinkList slow=L,fast=L; for(;fast&&fast->next;) slow=slow->next,fast=fast->next->next; return slow->data; } int main() { ios::sync_with_stdio(false); cin.tie(0);

关于广度优先查找和深度优先查找

风格不统一 提交于 2019-12-01 07:59:13
  由于最近在做的项目中设计到了虚拟dom的设计,那自然就避免不了需要对虚拟dom中的节点进行遍历/查找了,一般来说查找节点无非就两种方法 - 广度优先查找和深度优先查找,这跟我们在数据结构中学习到的树的遍历其实是一样的。ok,废话不多说,讲一下我对这两种查找方法的理解吧。   首先广度优先查找,BFS,它的一个特点就是应用到了队列的先进先出的特性,通过这个队列来存储第一次发现的节点,以便下一次的处理。 1 /** 2 * 3 * @param {*} target: 目标节点,要在哪个节点里面进行搜索 4 * @param {*} prop: 搜索索引 5 * 索引条件在isLegal()里面进行修改 6 */ 7 function breadthSearch(target){ 8 const nodeList = [target]; 9 let index = 0; 10 while (index < nodeList.length) { 11 const node = nodeList[index++]; 12 if (node.children && node.children.length > 0) { 13 for (let k in node.children) { 14 nodeList.push(node.children[k]); 15 } 16 } 17 }

《算法》笔记 8 - 二叉查找树

99封情书 提交于 2019-11-30 18:01:52
二叉查找树 查找 插入 性能 有序性相关的操作 最大键、最小键 向上取整、向下取整 选择、排名 范围查找 删除操作 删除最大键、最小键 通用删除操作 二叉查找树 前面了解的无序链表和有序数组在性能方面至少在线性级别,无法用于数据量大的场合。接下来要学习的二叉查找树可以将链表插入的灵活性和有序数组查找的高效性结合起来,是计算机科学中最重要的算法之一。 一个二叉查找树(Binary Search Tree)是一颗二叉树,其中每个结点都含有一个Comparable的键,以及相关联的值,且每个结点的键都大于其左子树中任意结点的键,小于右子树中任意结点的键。 查找 在二叉查找树中查找时,如果树是空的,则查找未命中;如果被查找的键和根结点的键相等,查找命中,否则就递归地在子树中继续查找,如果被查找的键小于根结点,就选择左子树,否则选择右子树。 查找算法的代码实现为: public class BST<Key extends Comparable<Key>, Value> { private Node root; private class Node { private Key key; private Value val; private Node left, right; public int size; public Node(Key key, Value val, int size) {

0928 笔记

倖福魔咒の 提交于 2019-11-30 16:47:37
目录 包 1.什么是包 2.为什么要有包 3.包的导入 1.import + 包名 2.from + 包名 + import + 模块名 3.from + 包名.模块名 + import + 成员名 4.总结 5.绝对导入与相对导入 time模块 1.时间戳 2.格式化时间 3.结构化时间 4.不同格式时间互相转换 结构化时间转格式化时间 格式化时间转结构化时间 结构化时间转时间戳 时间戳转结构化时间 datetime模块 1.当前时间 2.时间加减 random模块 1.随机0-1的小数 2.指定范围随机整数 3.打乱随机 4.随机取一个数 5.只随机一次 6.随机取两个数 hashlib模块 md5算法 hamc模块 typing模块 作用 requests模块 re模块 re.findall() 元字符 1. ^ 以...开头 2. $ 以..结尾 3. . 任意字符 4. \d 数字 获取所有数字 5. \D : 非数字 6. \w 非空 7. \W 空 8. \s 空 9. \S 非空 二 1. + 至少一个 2. ? 有 0-1个 3. * 0到无穷个 4. [] 限定取 5. [^] 限定不取 6. [|] 或 7. {2} 限定数量为2 8. {1,3} 限定数量范围 包 1.什么是包 包是模块的一种形式,包的本质就是一个含有 .py 的文件的文件夹 2

查找算法(3)--Interpolation search--插值查找

我的梦境 提交于 2019-11-30 16:14:29
1. 插值查找   (1)说明     在介绍插值查找之前,首先考虑一个新问题,为什么上述算法一定要是折半,而不是折四分之一或者折更多呢?     打个比方,在英文字典里面查“apple”,你下意识翻开字典是翻前面的书页还是后面的书页呢?如果再让你查“zoo”,你又怎么查?很显然,这里你绝对不会是从中间开始查起,而是有一定目的的往前或往后翻。     同样的,比如要在取值范围1 ~ 10000 之间 100 个元素从小到大均匀分布的数组中查找5, 我们自然会考虑从数组下标较小的开始查找。     经过以上分析,折半查找这种查找方式,不是自适应的(也就是说是傻瓜式的)。二分查找中查找点计算如下:        mid=(low+high)/2, 即mid=low+1/2*(high-low);     通过类比,我们可以将查找的点改进为如下:        mid=low+(key-a[low])/(a[high]-a[low])*(high-low),     也就是将上述的比例参数1/2改进为自适应的,根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字key,这样也就间接地减少了比较次数。     (2)基本思想:     基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。   注:对于表长较大

python 字典

纵饮孤独 提交于 2019-11-30 14:44:45
dict Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 举个例子,假设要根据同学的名字查找对应的成绩,如果用list实现,需要两个list: names = ['Michael', 'Bob', 'Tracy'] scores = [95, 75, 85]给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,list越长,耗时越长。 如果用dict实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。用Python写一个dict如下: >>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} >>> d['Michael'] 95 注意符号: list=[ ] dict={ } 为什么dict查找速度这么快? 因为dict的实现原理和查字典是一样的。 假设字典包含了1万个汉字,我们要查某一个字, 一个办法是把字典从第一页往后翻,直到找到我们想要的字为止,这种方法就是在list中查找元素的方法,list越大,查找越慢。 第二种方法是先在字典的索引表里(比如部首表)查这个字对应的页码,然后直接翻到该页,找到这个字。无论找哪个字