查找算法

数据结构与算法常见面试题1

烈酒焚心 提交于 2020-02-24 20:22:00
1.八大数据结构及其应用场景(数组、栈、链表、树、图、堆、散列表) 1.数组 数据结构中最基本的一个结构就是线性结构,而线性结构又分为连续存储结构和离散存储结构。连续存储结构其实就是数组。 在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。 使用场景 数组在以下三个情形下很有用: 1)数据量较小。 2)数据规模已知。 3)随机访问,修改元素值。 如果插入速度很重要,选择无序数组。如果查找速度很重要,选择有序数组,并使用二分查找。 缺点 1)需要预先知道数据规模 2)插入效率低,因为需要移动大量元素。 2.栈 是只能在某一端插入和删除的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。 使用场景 1.十进制与其它进制间的转换 125→1111111 2.行编辑器 #退格 @清除 3.平衡符号的判断 {[()()]} 4.中缀表达式转后缀表达式 顺序栈 优点 1)在输入数据量可预知的情形下,可以使用数组实现栈,并且数组实现的栈效率更高

算法(二维数组的查找)

不羁岁月 提交于 2020-02-24 14:26:20
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 要设计到二维数组中元素的查找,可以从左下或者右上开始查找,具体代码如下: public class Solution { public boolean Find ( int target , int [ ] [ ] array ) { if ( array == null || array . length == 0 || array [ 0 ] . length == 0 ) return false ; boolean flag = false ; for ( int j = 0 ; j < array [ 0 ] . length ; j ++ ) { if ( array [ array . length - 1 ] [ j ] >= target ) { for ( int i = 0 ; i < array . length ; i ++ ) { if ( array [ i ] [ j ] == target ) { flag = true ; } } } } return flag ; } } 来源: CSDN 作者: weixin_44857975 链接: https:/

哈希表

ⅰ亾dé卋堺 提交于 2020-02-24 12:09:55
前言 # 哈希表,又名散列表。是非常常用的一种数据结构,C#的Hashtable、字典,Java的HashMap,Redis的Hash,其底层实现都是散列表。而在一些互联网公司的面试中,更是技术面试官们必问的一道题目。本文将简单了解哈希表(散列表)这种数据结构。 一、散列表 # 1.1 散列表 # 散列表(哈希表),其思想主要是基于数组支持按照下标随机访问数据时间复杂度为O(1)的特性。可是说是数组的一种扩展。假设,我们为了方便记录某高校数学专业的所有学生的信息。要求可以按照学号(学号格式为:入学时间+年级+专业+专业内自增序号,如2011 1101 0001)能够快速找到某个学生的信息。这个时候我们可以取学号的自增序号部分,即后四位作为数组的索引下标,把学生相应的信息存储到对应的空间内即可。 如上图所示,我们把学号作为key,通过截取学号后四位的函数后计算后得到索引下标,将数据存储到数组中。当我们按照键值(学号)查找时,只需要再次计算出索引下标,然后取出相应数据即可。以上便是散列思想。 1.2 散列函数 # 上面的例子中,截取学号后四位的函数即是一个简单的散列函数。 Copy //散列函数 伪代码 int Hash(string key) { // 获取后四位字符 string hashValue =int.parse(key.Substring(key.Length-4, 4)

算法导论:Trie字典树

a 夏天 提交于 2020-02-23 15:13:45
1、 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树。 Trie一词来自re trie ve,发音为/tri:/ “tree”,也有人读为/traɪ/ “try”。 Trie树可以利用字符串的公共前缀来节约存储空间。如下图所示,该trie树用10个节点保存了6个字符串pool、prize、preview、prepare、produce、progress 在该trie树中,字符串preview,prepare公共前缀是“pre”,因此可以只存储一份“pre”以节省空间。当然,如果系统中存在大量字符串且这些字符串基本没有公共前缀,则相应的trie树将非常消耗内存,这也是trie树的一个缺点。 Trie树的基本性质可以归纳为: (1)根结点不包含字符,除根节点意外每个结点只包含一个字符。 (2)从根结点到某一个结点,路径上经过的字符连接起来,为该结点对应的字符串。 (3)每个结点的所有子结点包含的字符串不相同。 注意:每个结点可以有没有或者一个或者多个字结点,叶子结点没有子结点 2、数据结构表示 /** * 定义字典树的数据结构 * c 当前节点值 * isLeaf 是否是叶子结点 * children 孩子,key是孩子结点值,value是孩子结点的下一个字典树 * */ class

(转)查找算法:哈希查找

廉价感情. 提交于 2020-02-23 10:31:42
什么是哈希查找呢?在弄清楚什么是哈希查找之前,我们要弄清楚哈希技术,哈希技术是在记录的存储位置和记录的 key 之间建立一个确定的映射 f(),使得每个 key 对应一个存储位置 f(key)。若查找集合中存在这个记录,则必定在 f(key) 的位置上。哈希技术既是一种存储方法,也是一种查找方法。 六种哈希函数 f(key) 的构造方法: 1、直接定址法 哈希地址:f(key) = a*key+b (a,b为常数) 这种方法的优点是:简单,均匀,不会产生冲突。但是需要事先知道 key 的分布情况,适合查找表较小并且连续的情况。 2、数字分析法 比如我们的11位手机号码“136xxxx5889”,其中前三位是接入号,一般对应不同运营公司的子品牌,如130是联通如意通,136是移动神州行等等。中间四位表示归属地。最后四位才是用户号。 若我们现在要存储某家公司员工登记表,如果用手机号码作为 key,那么极有可能前7位都是相同的,所以我们选择最后四位作为 f(key) 就是不错的选择。 3、平方取中法 故名思义,比如 key 是1234,那么它的平方就是1522756,再抽取中间的3位就是227作为 f(key) 。 4、折叠法 折叠法是将 key 从左到右分割成位数相等的几个部分(最后一部分位数不够可以短些),然后将这几部分叠加求和,并按哈希表的表长,取后几位作为 f(key) 。

数据结构与算法18—哈希表(散列表)

≯℡__Kan透↙ 提交于 2020-02-23 10:29:44
哈希表的概念 哈希表(Hash Table)是一种特殊的数据结构,它最大的特点就是可以快速实现查找、插入和删除。 我们知道,数组的最大特点就是:寻址容易,插入和删除困难;而链表正好相反,寻址困难,而插入和删除操作容易。那么如果能够结合两者的优点,做出一种寻址、插入和删除操作同样快速容易的数据结构,那该有多好。这就是哈希表创建的基本思想,而实际上哈希表也实现了这样的一个“夙愿”,哈希表就是这样一个集查找、插入和删除操作于一身的数据结构。 哈希表 (Hash Table):也叫散列表,是根据关键码值(key-value)而直接进行访问的数据结构,也就是我们常用到的map。 哈希函数 :也称为是散列函数,是Hash表的映射函数,它可以把任意长度的输入变换成固定长度的输出,该输出就是 哈希值 。哈希函数能使对一个数据序列的访问过程变得更加迅速有效,通过哈希函数,数据元素能够被很快的进行定位。 哈希表和哈希函数的标准定义:若关键字为k,则其值存放在h(k)的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系f为哈希函数,按这个思想建立的表为哈希表。 设计出一个简单、均匀、存储利用率高的散列函数是散列技术中最关键的问题。 但是,一般散列函数都面临着冲突的问题。两个不同的关键字,由于散列函数值相同,因而被映射到同一表位置上。该现象称为冲突(Collision)或碰撞

哈希表之数学原理

自作多情 提交于 2020-02-23 10:03:42
.NET程序员,大多数时候是不需要数学的。因为,有了.NET, 数据结构和算法的重要性被弱化了,操作系统接口相关的东西被强化了。程序员只要求管理好代码,而不是设计好算法。 计算机,我只学会了技术,所以很多问题我都感觉似是而非,感觉是在学习一个API,而不是在学一门科学。 最近要实现一个哈希表,我查找了很多哈希函数,高下难分。而且,网上有很多人做了实验,但是,很多数据居然是矛盾的,有的说这个好,有的说那个好。于是我在想,有没有一种理想的最优函数,这样的函数的效率是多少。我的函数,只要接近于这个值就可以了。这样的理想函数的分析,就必须理解计算机的科学部分,这个是计算机科学永恒的部分。 首先,是一个很简单的也是很实用的问题: “给一个url 做一个hash 值,通过这个hash 值,查找这个url 是否已经在数据库中存在了,我相信很多人都做过这个问题,很多人采用把一个url 转换成一个无符号的int 类型,然后通过这个int 类型进行查找。现在的问题是,如果我的网站有1000万个url,会有多少个url 是发生哈希冲突呢,也就是说,url链接不一样,但是映射成了相同的哈希值。”有多少冲突,读完这篇文章你也就会算了。 我今天讲的只是哈希表中的一种类型:链地址哈希表。这种哈希表是最常用的哈希表,PHP数组的内部实现,就是采用这样的哈希表。估计.net 的字典类,也是通过这样的方法。

二分查找算法的递归与非递归实现(C++)

*爱你&永不变心* 提交于 2020-02-22 21:17:48
二分查找 又称 折半查找 , 首先, 假设表中元素是按升序排列, 将 表 中间位置 的关键字与查找关键字比较: 如果两者相等, 则查找成功; 否则利用中间位置将表分成前、 后两个子表: 如果中间位置的关键字大于查找关键字, 则进一步查找前一子表 否则进一步查找后一子表 重复以上过程, 直到找到满足条件的记录, 使查找成功, 或直到子表不存 在为止, 此时查找不成功。 二分查找算法的递归实现 //如果找到target,返回其所在数组下标,如果未找到,返回-1; int binary_search ( std :: vector < int > & sort_array , int begin , int end , int target ) { if ( begin > end ) { return - 1 ; } int mid = ( begin + end ) / 2 ; if ( target == sort_array [ mid ] ) { return mid ; } else if ( target < sort_array [ mid ] ) { return binary_search ( sort_array , begin , mid - 1 , target ) ; } else if ( target > sort_array [ mid ] ) {

KMP算法的next[]数组通俗解释

被刻印的时光 ゝ 提交于 2020-02-20 02:15:20
我们在一个母字符串中查找一个子字符串有很多方法。KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度。 当然我们可以看到这个算法针对的是子串有对称属性,如果有对称属性,那么就需要向前查找是否有可以再次匹配的内容。 在KMP算法中有个数组,叫做前缀数组,也有的叫next数组,每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符,当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大。 这个next数组的求法是KMP算法的关键,但不是很好理解,我在这里用通俗的话解释一下,看到别的地方到处是数学公式推导,看得都蛋疼,这个篇文章仅贡献给不喜欢看数学公式又想理解KMP算法的同学。 1、用一个例子来解释,下面是一个子串的next数组的值,可以看到这个子串的对称程度很高,所以next值都比较大。 位置i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 前缀next[i] 0 0 0 0 1 2 3 1 2 3 4 5 6 7 4 0 子串 a g c t a g c a g c t a g c t g 申明一下:下面说的对称不是中心对称,而是中心字符块对称,比如不是abccba,而是abcabc这种对称。 (1)逐个查找对称串。 这个很简单

KMP算法的next[]数组通俗解释

一曲冷凌霜 提交于 2020-02-20 02:10:49
KMP算法的next[]数组通俗解释 我们在一个母字符串中查找一个子字符串有很多方法。KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度。 当然我们可以看到这个算法针对的是子串有对称属性,如果有对称属性,那么就需要向前查找是否有可以再次匹配的内容。 在KMP算法中有个数组,叫做前缀数组,也有的叫next数组,每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符,当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大。 这个next数组的求法是KMP算法的关键,但不是很好理解,我在这里用通俗的话解释一下,看到别的地方到处是数学公式推导,看得都蛋疼,这个篇文章仅贡献给不喜欢看数学公式又想理解KMP算法的同学。 1、用一个例子来解释,下面是一个子串的next数组的值,可以看到这个子串的对称程度很高,所以next值都比较大。 位置i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 前缀next[i] 0 0 0 0 1 2 3 1 2 3 4 5 6 7 4 0 子串 a g c t a g c a g c t a g c t g 申明一下:下面说的对称不是中心对称,而是中心字符块对称,比如不是abccba,而是abcabc这种对称。 (1