时间复杂度

解决哈希冲突的三种方法(拉链法、开放地址法、再散列法)

孤街醉人 提交于 2019-12-21 11:48:48
上篇博客我们说到了,什么是哈希冲突,其实就是再采用哈希函数对输入域进行映射到哈希表的时候,因为哈希表的位桶的数目远小于输入域的关键字的个数,所以,对于输入域的关键字来说,很可能会产生这样一种情况,也就是,一个关键字会映射到同一个位桶中的情况,这种情况就就叫做哈希冲突,解决哈希冲突的有三种方案,一种叫做拉链法(也叫作链接法、链地址法,一个意思),另外三种分别为开发地址法和再散列法。 一、拉链法 上篇博文我们举的例子,HashMap,HashSet其实都是采用的拉链法来解决哈希冲突的,就是在每个位桶实现的时候,我们采用链表(jdk1.8之后采用链表+红黑树)的数据结构来去存取发生哈希冲突的输入域的关键字(也就是被哈希函数映射到同一个位桶上的关键字)。首先来看使用拉链法解决哈希冲突的几个操作: ①插入操作:在发生哈希冲突的时候,我们输入域的关键字去映射到位桶(实际上是实现位桶的这个数据结构,链表或者红黑树)中去的时候,我们先检查带插入元素x是否出现在表中,很明显,这个查找所用的次数不会超过装载因子(n/m:n为输入域的关键字个数,m为位桶的数目),它是个常数,所以插入操作的最坏时间复杂度为O(1)的。 ②查询操作:和①一样,在发生哈希冲突的时候,我们去检索的时间复杂度不会超过装载因子,也就是检索数据的时间复杂度也是O(1)的 ③删除操作

算法的时间与空间复杂度的计算

自闭症网瘾萝莉.ら 提交于 2019-12-21 08:03:32
算法(Algorithm)是指用来操作数据、解决程序问题的一组方法。对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。 那么我们应该如何去衡量不同算法之间的优劣呢? 主要还是从算法所占用的「时间」和「空间」两个维度去考量。 时间维度:是指执行当前算法所消耗的时间,我们通常用「时间复杂度」来描述。 空间维度:是指执行当前算法需要占用多少内存空间,我们通常用「空间复杂度」来描述。 因此,评价一个算法的效率主要是看它的时间复杂度和空间复杂度情况。然而,有的时候时间和空间却又是「鱼和熊掌」,不可兼得的,那么我们就需要从中去取一个平衡点。 下面我来分别介绍一下「时间复杂度」和「空间复杂度」的计算方式。 一、时间复杂度 我们想要知道一个算法的「时间复杂度」,很多人首先想到的的方法就是把这个算法程序运行一遍,那么它所消耗的时间就自然而然知道了。 这种方式可以吗?当然可以,不过它也有很多弊端。 这种方式非常容易受运行环境的影响,在性能高的机器上跑出来的结果与在性能低的机器上跑的结果相差会很大。而且对测试时使用的数据规模也有很大关系。再者,并我们在写算法的时候,还没有办法完整的去运行呢。 因此,另一种更为通用的方法就出来了:「 大O符号表示法 」,即 T(n) = O(f(n)) 我们先来看个例子: for(i=1; i<=n; ++i) { j

排序算法

*爱你&永不变心* 提交于 2019-12-21 05:46:38
1.快速排序: 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。 步骤为: 从数列中挑出一个元素,称为"基准"(pivot), 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为 分区(partition) 操作。 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 实现代码: def lessequal(value1,value2): return value1<=value2 def asc(ary,cmp=lessequal): if len(ary)<2: return ary else: pivot=ary[0] return asc([x for x in ary[1:] if cmp(x,pivot)],cmp)+[pivot]+asc([x for x in ary[1:] if not cmp(x,pivot)],cmp) def desc(ary,cmp=lessequal): if len(ary)<2: return ary else: pivot=ary[0] return desc([x for x in ary[1:] if not

十大经典排序算法

青春壹個敷衍的年華 提交于 2019-12-21 02:53:29
转自https://blog.csdn.net/hellozhxy/article/details/79911867 0、排序算法说明0.1 排序的定义 对一序列对象根据某个关键字进行排序。 0.2 术语说明 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面; 不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面; 内排序:所有排序操作都在内存中完成; 外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行; 时间复杂度: 一个算法执行所耗费的时间。 空间复杂度:运行完一个程序所需内存的大小。 例子 数据量低时,O(1) 和 O(n^2)的区别可以忽略不计。比如,你有个算法要处理2000条元素。 O(1) 算法会消耗 1 次运算 O(log(n)) 算法会消耗 7 次运算 O(n) 算法会消耗 2000 次运算 O(n*log(n)) 算法会消耗 14,000 次运算 O(n^2) 算法会消耗 4,000,000 次运算 O(1) 和 O(n^2) 的区别似乎很大(4百万),但你最多损失 2 毫秒,只是一眨眼的功夫。确实,当今处理器每秒可处理上亿次的运算。这就是为什么性能和优化在很多IT项目中不是问题。 我说过,面临海量数据的时候,了解这个概念依然很重要。如果这一次算法需要处理 1,000,000 条元素

数据结构错题汇总

纵然是瞬间 提交于 2019-12-20 23:48:50
第一章: (3)通常要求同一逻辑结构中的所有数据元素具有相同的特性,这意味着( )。 A.数据具有同一特点 B.不仅数据元素所包含的数据项的个数要相同,而且对应数据项的类型要一致 C.每个数据元素都一样 D.数据元素所包含的数据项的个数要相等 答案:B (6)以下数据结构中,( )是非线性数据结构 A.树 B.字符串 C.队列 D.栈 答案:A 第二章: (2)在n个结点的顺序表中,算法的时间复杂度是O(1)的操作是( )。 A.访问第i个结点(1≤i≤n)和求第i个结点的直接前驱(2≤i≤n) B.在第i个结点后插入一个新结点(1≤i≤n) C.删除第i个结点(1≤i≤n) D.将n个结点从小到大排序 答案:A 解释:在顺序表中插入一个结点的时间复杂度都是O(n2),排序的时间复杂度为O(n2)或O(nlog2n)。顺序表是一种随机存取结构,访问第i个结点和求第i个结点的直接前驱都可以直接通过数组的下标直接定位,时间复杂度是O(1)。 (5)线性表若采用链式存储结构时,要求内存中可用存储单元的地址( )。 A.必须是连续的 B.部分地址必须是连续的 C.一定是不连续的 D.连续或不连续都可以 答案:D (8)将两个各有n个元素的有序表归并成一个有序表,其最少的比较次数是( )。 A.n B.2n-1 C.2n D.n-1 答案:A 解释:当第一个有序表中所有的元素都小于(或大于

时间空间复杂度的解释

[亡魂溺海] 提交于 2019-12-20 19:27:39
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 何为时间空间复杂度? 《 1 》空间复杂度 O ( N ): 一个算法在运行过程中临时占用存储空间大小的量度。一个算法的空间复杂度只考虑在运行过程中为局部变量分配的存储空间的大小,它包括为参数表中形参变量分配的存储空间和为在函数体中定义的局部变量分配的存储空间两个部分。 举例: ( 1 )如一个算法的空间复杂度为一个常量,即不随被处理数据量 n 的大小而改变时,可表示为 O(N) ( 2 )当一个算法的空间复杂度与以 2 为底的 n 的对数成正比时,可表示为 O(log2n) ( 3 )当一个算法的空间复杂度与 n 成线性比例关系时,可表示为 O(n) ( 4 )递归函数的时间复杂度是 O(N) ,因每次递归都需保存函数内部局部变量的存储空间。 《 2 》时间复杂度 它定量描述了该算法的运行时间。算法的基本操作重复执行的次数是模块 n 的某一个函数 f(n) ,因此,算法的时间复杂度记做 :T(n)=O(f(n)) 。随着模块 n 的增大,算法执行的时间的增长率和 f(n) 的增长率成正比,所以 f(n) 越小,算法的时间复杂度越低,算法的效率越高。 常见的时间复杂度有 : 常数阶 O(1), 对数阶 O(log2n), 线性阶 O(n), 线性对数阶 O(nlog2n), 平方阶 O(n^2) ,立方阶 O

java 时间复杂度和空间复杂度

给你一囗甜甜゛ 提交于 2019-12-20 19:27:27
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 同一问题可用不同 算法 解决,而一个算法的质量优劣将影响到算法乃至 程序 的效率。算法分析的目的在于选择合适算法和改进算法。 算法复杂度 分为时间复杂度和 空间复杂度 。其作用: 时间复杂度是度量算法执行的时间长短;而空间复杂度是度量算法所需存储空间的大小。 1、时间复杂度 1.1 时间频度 一个算法中的语句执行次数称为语句频度或时间频度。记为T(n) 1.2 时间复杂度 一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。 在各种不同算法中,若算法中语句执行次数为一个常数,则时间复杂度为O(1),另外,在时间频度不相同时,时间复杂度有可能相同,如 T(n)=n2+3n+4与T(n)=4n2+2n+1它们的频度不同,但时间复杂度相同,都为O(n2)。 按数量级递增排列,常见的时间复杂度有:常数阶O(1),对数阶O(log2n),线性阶O(n), 线性对数阶O(nlog2n),平方阶O(n2),立方阶O(n3),..., k次方阶O(nk),指数阶O(2n)。

算法的时间与空间复杂度

情到浓时终转凉″ 提交于 2019-12-20 19:24:12
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 算法(Algorithm)是指用来操作数据、解决程序问题的一组方法。对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。 P.S. 算法其实有很多定义。 那么我们应该如何去衡量不同算法之间的优劣呢? 主要还是从算法所占用的「时间」和「空间」两个维度去考量。 时间维度:是指执行当前算法所 消耗的时间 ,我们通常用「时间复杂度」来描述。 空间维度:是指执行当前算法需要 占用多少内存空间 ,我们通常用「空间复杂度」来描述。 因此,评价一个算法的效率主要是看它的时间复杂度和空间复杂度情况。然而,有的时候时间和空间却又是「鱼和熊掌」,不可兼得的,那么我们就需要从中去取一个平衡点。 下面我来分别介绍一下「时间复杂度」和「空间复杂度」的计算方式。 一、时间复杂度 我们想要知道一个算法的「时间复杂度」,很多人首先想到的的方法就是把这个算法程序运行一遍,那么它所消耗的时间就自然而然知道了。 这种方式可以吗?当然可以,不过它也有很多弊端。 这种方式非常容易受运行环境的影响,在性能高的机器上跑出来的结果与在性能低的机器上跑的结果相差会很大。而且对测试时使用的数据规模也有很大关系。再者,我们在写算法的时候,还没有办法完整的去运行呢。 因此,另一种更为通用的方法就出来了:「

时间复杂度深入浅出

时光毁灭记忆、已成空白 提交于 2019-12-20 09:02:55
[转] https://blog.csdn.net/qq_41523096/article/details/82142747 精简易懂!!!!! 时间复杂性 ,又称 时间复杂度 , 算法 的 时间复杂度 是一个 函数 ,它定性描述该算法的运行时间。这是一个代表算法输入值的 字符串 的长度的函数。时间复杂度常用 大O符号 表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是 渐近 的,亦即考察输入值大小趋近无穷时的情况。 为了计算时间复杂度,我们通常会估计算法的操作单元数量,每个单元运行的时间都是相同的。因此,总运行时间和算法的操作单元数量最多相差一个常量系数。 相同大小的不同输入值仍可能造成算法的运行时间不同,因此我们通常使用算法的最坏情况复杂度,记为 T ( n ) ,定义为任何大小的输入 n 所需的最大运行时间。另一种较少使用的方法是平均情况复杂度,通常有特别指定才会使用。时间复杂度可以用函数 T ( n ) 的自然特性加以分类,举例来说,有着 T ( n ) = O ( n ) 的算法被称作“线性时间算法”;而 T ( n ) =O(M^n) 和 M = O( T ( n )) ,其中 M ≥ n > 1 的算法被称作“指数时间算法”。 一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多

数据结构与算法--栈、队列(队列)

馋奶兔 提交于 2019-12-20 00:21:39
Hello,everybody.我们又见面了。今天我们来学习一下队列这个数据结构,let’s Go,开始我们的征程吧。 首先,举两个生活中的常见例子。相信大家,在用电脑工作娱乐时,都会碰到这样的现象。当我们点击程序或进行其他操作时,电脑处于死机状态。正当我们准备Reset时,它突然像打了鸡血似的,突然把刚才我们的操作,按顺序执行了一遍。之所以会出现这个现象,是因为操作系统的多个程序,需要通过一个管道输出,而按先后顺序排队造成的。 还有有个例子,在我们打客服热线时,有时会出现等待的现象。当其他客户挂断电话,客服人员才会接通我们的电话。因为客服人员相对于客户而言,总是不够的,当客户量大于客服人员时,就会造成排队等待的想象。 操作系统、客服系统,都是应用了一种数据结构才实现了这种先进先出的排队功能,这个数据结构就是队列。 队列(Queue): 是只允许在一端进行插入操作,在另一端进行删除操作的线性表。 队列也是一种特殊的线性表,是一种先进先出的线性表。允许插入的一端称为表尾,允许删除的一端称为表头。 上图,很形象的表示了队列的结构。排在前面的先出,排在后面的后出。换句话,先进的先出,后进额后出。我们在队尾插入数据,队头删除数据。 队列的抽象数据类型: 同样是线性表,队列也有类似线性表的操作,不同的是,插入操作只能在队尾,删除操作只能在队头。 上图是队列的抽象数据类型。 顺序存储的队列: