数据结构

数据结构与算法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:23:25
一、哈希表 哈希表又称散列表。 哈希表存储的基本思想是:以数据表中的每个记录的关键字k为自变量,通过一种函数H(k)计算出函数值。把这个值解释为一块连续存储空间(即数组空间)的单元地址(即下标),将该记录存储到这个单元中。 在此称该函数H为哈希函数或散列函数。按这种方法建立的表称为哈希表或散列表。 例如,要将关键字值序列(3,15,22,24),存储到编号为0到4的表长为5的哈希表中。 计算存储地址的哈希函数可取除5的取余数算法H(k)=k% 5。则构造好的哈希表如图所示。 理想情况下,哈希函数在关键字和地址之间建立了一个一一对应关系,从而使得查找只需一次计算即可完成。由于关键字值的某种随机性,使得这种一一对应关系难以发现或构造。因而可能会出现不同的关键字对应一个存储地址。即 k1≠k2 , 但 H(k1)=H(k2 ), 这种现象称为 冲突 。 把这种具有不同关键字值而具有相同哈希地址的对象称 “ 同义词 ” 。 在大多数情况下,冲突是不能完全避免的。这是因为所有可能的关键字的集合可能比较大,而对应的地址数则可能比较少。 对于哈希技术,主要研究两个问题: (1)如何设计哈希函数以使冲突尽可能少地发生。 (2)发生冲突后如何解决 。 二、哈希函数 构造好的 哈希函数 的方法,应能使冲突尽可能地少,因而应具有较好的随机性。这样可使一组关键字的散列地址均匀地分布在整个地址空间

数据结构和算法(绪论)

会有一股神秘感。 提交于 2020-02-23 04:29:58
数据结构和算法绪论 数据结构:数据结构是一门研究非数值计算的程序设计问题中的操作对象,以及它们之 间的关条和操作等相关问题的学科。 数据结构就是关糸,就是数据元素相互之间存在的一种或多种特定关系的集合。 程序设计=数据结构+算法 传统上,数据结构分为逻辑结构和物理结构。 逻辑结构:是指数据对象中数据元素之间的相互关系。 物理结构:是指数据的逻辑结构在计算机中的存储形式。 四大逻辑结构: 集合 结构中的数据元素除了同属于一个集合外,它们之间没有任何其他关系。 线性结构 中的数据元素之间是一对一的关系。 树形结构 中的数据元素之间存在一种一对多的层次关系。 图形结构 (网状结构)中的数据元素之间是多对多关系。 物理结构又称存储结构,实际上研究的的就是如何把数据元素存储到计算机的存储器中。(存储器主要是针对内存而言的,像硬盘、光盘等外部存储器的数据组织通常用文件结构来描述。) 数据元素的存储结构形式有两种:顺序存储和链式存储。 顺序存储结构 :是把数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的。例如我们编程语言的数组结构就是这样滴。 链式存储结构 :是把数据元素存放在任意的存储单元里,这组存储单元可以是连续的,也可以是不连续的。这样说的话链式存储结构的数据元素存储关糸并不能反映其逻辑关糸,因此需要用一个指针存放数据元素的地址

数据结构与算法之图(上)

懵懂的女人 提交于 2020-02-23 04:05:13
什么是图 图是一种非常强大的数据结构,图是由顶点的有穷非空集合和顶点之间边的集合组成,通 常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。 当我们需要处理多对多这么一种关系时,我们就可以建立一张图来解决。图中的顶点是我 们的数据元素(线性表中我们把数据元素叫元素,树中叫结点,在图中数据元素我们则称 之为顶点),边就是这些研究对象之间的关系,通常称之为权重,具体应用中会有不同。 怎么存储图 邻接矩阵 用一个二维数组存放节点,节点之间有边的就把对应的数组元素赋值位1,代表存在。 邻接矩阵的好处就是能够直观的看到那些边之间存在关系,便于查询(只要输入你要查询 的两个顶点值便可以确定他在这个二维数组当中的位置),计算每一个顶点的入度或出度 时只需遍历一遍即可。 代码实现邻接矩阵构建图: 但我们不难发现这个二维数组沿红线分开的两部分是完全对称的,且红线上的值都为0(自 己到自己肯定是没有边的啦),精打细算的我们就会想能不能那一半不用可以节省点空间 啊! 于是我们有了上面这个解决方案,他优化了邻接矩阵的空间复杂度,但他也制造了一些不 便,变成一个一维数组来存储之后,查询是否存在边变得没那么容易,如果我们要查询点 V i 与V j 之间有没有边就要查询a[i*(i+1)/2+j]了。但无论怎样还是节省了空间。

数据结构和算法-面试题

为君一笑 提交于 2020-02-23 03:02:20
########################################## """ 数据结构: 1,用Python代码简单实现一个栈。实现pop/push及max方法,要求能在O(1)时间内取得最大值。 排序算法: 写个快速排序热热身,分析一下复杂度,如果不使用额外的空间,应该怎么写?快排平均复杂度多少,最坏情况如何优化; 请列举常见排序并通过代码实现任意三种。冒泡/选择/插入/快排 几种常用排序的算法复杂度是多少; 单向链表如何使用快速排序算法进行排序; 查找算法: 用Python实现一个二分查找的函数。 请列举常见查找并通过代码实现任意三种。无序查找/二分查找/插值查找 如何遍历一个内部未知的文件夹(两种树的优先遍历方式) 算法复杂度 手写:一个长度n的无序数字元素列表,如何求中位数,如何尽快的估算中位数,你的算法复杂度是多少; 手写:已知一个长度n的无序列表,元素均是数字,要求把所有间隔为d的组合找出来,你写的解法算法复杂度多少; list,dict和数据结构和算法 1,Python中的列表是如何实现的?Python中的列表使用了分离式技术实现的动态顺序表。 2,Python中列表的索引查询的时间复杂度是多少?O(1) 3,dict与list的查找复杂度?dict用hash实现,查找的时间复杂度是O(1),list则为O(n)。 """ ##############

数据结构与算法作业27.移除元素

て烟熏妆下的殇ゞ 提交于 2020-02-22 18:55:08
27.移除元素 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。 示例 2: 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。 注意这五个元素可为任意顺序。 你不需要考虑数组中超出新长度后面的元素。 原题链接 public class Solution { public : int removeElement ( vector < int > & nums , int val ) { int i = 0 ; for ( int j = 0 ; j < nums . size ( ) ; j ++ ) { if ( nums [ j ] != val ) { nums [ i ] = nums [ j ] ; i ++ ; } } return i ; } } ; 来源:

数据结构和算法(算法)

梦想与她 提交于 2020-02-22 16:33:06
数据结构和算法的关系,就是一对好朋友,不离不弃。 算法 是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。(学习的技巧和方式) 对于给定的问题,可以有多种算法来解决。 算法的五个基本特征:输入、输出、有穷性、确定性和可行性。 输入 :算法具有零个或多个输入。 输出 :算法至少有一个或多个输出。 有穷性 :算法执行有限个步骤后,自动结束而不会无限循环,并且每个步骤在可接受的时间内完成。 确定性 :算法的每一个步骤都具有确定的含义,不会出现二义性。 算法在一定条件下,只有一条执行路径,相同的输入只能有唯一的输出结果。 算法的每个步骤都应该被精确定义而无歧义。 可行性 :算法的每一步都必须是可行的,也就是说,每一步都能够通过执行有限次数完成。 算法设计的要求 正确性 :算法的正确性是指算法至少应该具有输入、输出和加工处理无歧义性、能正确反映问题的需求、能够得到问题的正确答索。 大体分为以下四个层次: 1算法程序没有语法错误。 2 算法程序对于合法输入能够产生满足要求的输出。 3算法程序对于非法输入能够产生满足规格的说明。 4算法程序对于故意刁难的测试输入都有满足要求的输出结果。 可读性 :算法设计另一目的是为了便于阋读、理解和交流。 健壮性 :当输入数据不合法时,算法也能做出相关处理,而不是产生异常、崩溃或莫名其妙的结果。 时间效率高和存储量低

数据结构篇——数组扩展(稀疏数组)

天大地大妈咪最大 提交于 2020-02-22 16:02:45
其实稀疏数组更多的是一种思想,而不是一种全新独立的数据结构。它本质上也就是一个二维数组。 稀疏数组简介以及应用场景 当一个数组容量很大,但是其中 有效数据很少且是稀疏分布 时,我们就可以使用稀疏数组来减少不必要的内存消耗。 注 :这里的有效数据,也可以理解为与绝大部分数据不同的。加上这个理解后,稀疏数组的应用场景会多很多。 其实思想很简单,构建出来一个二维数组,然后把有效数据的坐标都一一标记出来放进二维数组中。 稀疏数组的结构 稀疏数组本质上也是一个数组。 稀疏数组由(N+1)x3构成。 第一行的三个值依次表示 原数组的行号 原数组的列号 有几个格子有数据 之后的每一行都表示一个特定的值。 有意义值的行号 有意义值的列号 有意义的值 所以我们可以得到假设一个数组有效值数量为N,则他的行数为N+1。 通过稀疏数组的结构,我们又能得到一个信息。 稀疏数组比较适合用来处理规整数组(即矩阵) ,如果不是矩阵但同时又满足稀疏数组应用场景的,可以通过数组补齐的方式,把原数组变成矩阵。 稀疏数组实现 public class SparseArray { /** * 把普通二维规整数组变成稀疏数组 * * @param array 二维规整数组 * @param defaultValue 二维数组中默认的值(大部分坐标的值) * @return 稀疏数组 */ public static int

数据结构实验之二叉树六:哈夫曼编码

痞子三分冷 提交于 2020-02-22 12:31:04
Description 字符的编码方式有多种,除了大家熟悉的ASCII编码,哈夫曼编码(Huffman Coding)也是一种编码方式,它是可变字长编码。该方法完全依据字符出现概率来构造出平均长度最短的编码,称之为最优编码。哈夫曼编码常被用于数据文件压缩中,其压缩率通常在20%~90%之间。你的任务是对从键盘输入的一个字符串求出它的ASCII编码长度和哈夫曼编码长度的比值。 Input 输入数据有多组,每组数据一行,表示要编码的字符串。 Output 对应字符的ASCII编码长度la,huffman编码长度lh和la/lh的值(保留一位小数),数据之间以空格间隔。 Sample Input AAAAABCD THE_CAT_IN_THE_HAT Output 64 13 4.9 144 51 2.8 Hint #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; bool cmp(int a,int b) { return a>b; } int main() { char str[1000]; while(scanf("%s",str)!=EOF) { char s[1000]; int sn[1000]={0}; int len

最近关于编程学习的一点小体会

梦想的初衷 提交于 2020-02-22 06:21:10
从来没有如此专注于编程过,即使在大一学习课程中学习C++时也未有过这样主动,不觉厌烦,就更不用说Java学习的时候了,那时候就是上课吧,然而感觉效率一点也没有,根本没有心去学习,而那时也觉得编程如此难学。经过时间的打磨,可能是成长了不少,懂得了编程的重要,也或许是终于开窍,对于编程的学习由被动变为了主动,总之,态度上的转变是肯定有的。也算是悬崖勒马,及时回头,我相信都还来的及! 这一周脑袋一直装着二柱子的那个题,在上周的基础上老师又提出了更高的要求。选择打印方式,是否有乘除法,数字范围,这都是不难解决的问题,花时间最多的就是括号的使用,如何在由多个数组成的个运算式中加入(),成了我走路,吃饭甚至睡觉都在思考的问题。可能思路很简单,但是如何实现就不是那么容易了,两个数时简单,可以在输出时就加上括号,然后在多个数参与运算的表达式中如何插入括号呢?后来想到了用字符串,因为字符串之间的加法很简单,好比string3=string1+‘('+string2+')' ,一样很容易实现,然而要把整型与字符型的元素合在一起就没那么就简单了,所以想到了用itoa()函数把整型转换成字符串型。括号的插入实现。 然而,运算过程中是否除得尽,在长的运算式中就会很麻烦,这使我想到数据结构中的堆栈,可以实现对四则运算的运算,如果在计算的过程中加入是否除尽的判断,那么问题将会迎刃而解。然而问题又来了