ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:83.75KB ,
资源ID:17963599      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/17963599.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(精品算法合集之《浅谈跳跃表的相关操作及其应用》Word格式文档下载.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

精品算法合集之《浅谈跳跃表的相关操作及其应用》Word格式文档下载.docx

1、它会从功能、效率等方面对跳跃表作一个初步的介绍,并给出其图形结构,以便读者对跳跃表有个形象的认识。第二部分将介绍跳跃表的三种基本操作查找,插入和删除,并对它们的时空复杂度进行分析。 第三部分是对跳跃表应用的介绍,并通过实际测试效果来对跳跃表以及其它一些相关数据结构进行对比,体现其各自的优缺点。 最后一部分是对跳跃表数据结构的总结。【概述及结构】二叉树是我们都非常熟悉的一种数据结构。它支持包括查找、插入、删除等一系列的操作。但它有一个致命的弱点,就是当数据的随机性不够时,会导致其树型结构的不平衡,从而直接影响到算法的效率。跳跃表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进

2、行查找、插入、删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领。而且最重要的一点,就是它的编程复杂度较同类的AVL树,红黑树等要低得多,这使得其无论是在理解还是在推广性上,都有着十分明显的优势。首先,我们来看一下跳跃表的结构(如图1) 53 45 37 30 29 15 11 - + 图1 有7个元素的跳跃表S0 S1 S2 S3 跳跃表由多条链构成(S0,S1,S2 ,Sh),且满足如下三个条件:(1) 每条链必须包含两个特殊元素:+ 和 -(2) S0包含所有的元素,并且所有链中的元素按照升序排列。(3) 每条链中的元素集合必须包含于序数较小的链的元素集合,即:【基

3、本操作】在对跳跃表有一个初步的认识以后,我们来看一下基于它的几个最基本的操作。一、 查找目的:在跳跃表中查找一个元素x 在跳跃表中查找一个元素x,按照如下几个步骤进行:i) 从最上层的链(Sh)的开头开始ii) 假设当前位置为p,它向右指向的节点为q(p与q不一定相邻),且q的值为y。将y与x作比较(1) x=y 输出查询成功及相关信息(2) xy 从p向右移动到q的位置(3) xy 从p向下移动一格iii) 如果当前位置在最底层的链中(S0),且还要往下移动的话,则输出查询失败图2 查询元素53的全过程 二、插入 目的:向跳跃表中插入一个元素x 首先明确,向跳跃表中插入一个元素,相当于在表中

4、插入一列从S0中某一位置出发向上的连续一段元素。有两个参数需要确定,即插入列的位置以及它的“高度”。 关于插入的位置,我们先利用跳跃表的查找功能,找到比x小的最大的数y。根据跳跃表中所有链均是递增序列的原则,x必然就插在y的后面。 而插入列的“高度”较前者来说显得更加重要,也更加难以确定。由于它的不确定性,使得不同的决策可能会导致截然不同的算法效率。为了使插入数据之后,保持该数据结构进行各种操作均为O(logn)复杂度的性质,我们引入随机化算法(Randomized Algorithms)。我们定义一个随机决策模块,它的大致内容如下:产生一个0到1的随机数r r random()如果r小于一个

5、常数p,则执行方案A, if rp then do A 否则,执行方案B else do B初始时列高为1。插入元素时,不停地执行随机决策模块。如果要求执行的是A操作,则将列的高度加1,并且继续反复执行随机决策模块。直到第i次,模块要求执行的是B操作,我们结束决策,并向跳跃表中插入一个高度为i的列。性质1: 根据上述决策方法,该列的高度大于等于k的概率为pk-1。此处有一个地方需要注意,如果得到的i比当前跳跃表的高度h还要大的话,则需要增加新的链,使得跳跃表仍满足先前所提到的条件。我们来看一个例子:假设当前我们要插入元素“40”,且在执行了随机决策模块后得到高度为4步骤一:找到表中比40小的最

6、大的数,确定插入位置图3.1 确定插入的位置插入的位置步骤二:插入高度为4的列,并维护跳跃表的结构图3.2 插入高度为4的列,并维护跳跃表40 注意加入新的链 三、删除从跳跃表中删除一个元素x 删除操作分为以下三个步骤:(1) 在跳跃表中查找到这个元素的位置,如果未找到,则退出 *(2) 将该元素所在整列从表中删除 *(3) 将多余的“空链”删除 *图4.1 删除元素11的全过程图4.2 删除以后的结构四、“记忆化”查找(Search with fingers)所谓“记忆化”查找,就是在前一次查找的基础上进行进一步的查找。它可以利用前一次查找所得到的信息,取其中可以被当前查找所利用的部分。利用

7、“记忆化”查找可以将一次查找的复杂度变为O(logk),其中k为此次与前一次两个被查找元素在跳跃表中位置的距离。下面来看一下记忆化搜索的具体实现方法:假设上一次操作我们查询的元素为i,此次操作我们欲查询的元素为j。我们用一个update数组来记录在查找i时,指针在每一层所“跳”到的最右边的位置。如图4.1中橘黄色的元素。(蓝色为路径上的其它元素)图4.1 查找元素37 在插入元素j时,分为两种情况:(1) ij从S0层开始向上遍历update数组中的元素,直到找到某个元素小于等于j,并于此处开始新一轮对j的查找(与一般的查找过程相同) 图4.2十分详细地说明了在查找了i=37之后,继续查找j=

8、15或53时的两种不同情况。图4.2 新一轮查找元素为15(53)的步骤流程 记忆化查找(Search with fingers)技术对于那些前后相关性较强的数据效率极高,这点可以在后文中的实际测试报告中略见一斑。【复杂度分析】一个数据结构的好坏大部分取决于它自身的空间复杂度以及基于它一系列操作的时间复杂度。跳跃表之所以被誉为几乎能够代替平衡树,其复杂度方面自然不会落后。我们来看一下跳跃表的相关复杂度:空间复杂度: O(n) (期望)跳跃表高度: O(logn) (期望)相关操作的时间复杂度: 查找: O(logn) (期望) 插入: 删除:之所以在每一项后面都加一个“期望”,是因为跳跃表的复

9、杂度分析是基于概率论的。有可能会产生最坏情况,不过这种概率极其微小。下面我们来一项一项分析。一、 空间复杂度分析 O(n)假设一共有n个元素。根据性质1,每个元素插入到第i层(Si)的概率为pi-1 ,则在第i层插入的期望元素个数为npi-1,跳跃表的元素期望个数为 ,当p取小于0.5的数时,次数总和小于2n。所以总的空间复杂度为O(n)二、跳跃表高度分析 O(logn)根据性质1,每个元素插入到第i层(Si)的概率为pi ,则在第i层插入的期望元素个数为npi-1。考虑一个特殊的层:第1+层。层的元素期望个数为 = 1/n2,当n取较大数时,这个式子的值接近0,故跳跃表的高度为O(logn)

10、级别的。三、查找的时间复杂度分析 O(logn)我们采用逆向分析的方法。假设我们现在在目标节点,想要走到跳跃表最左上方的开始节点。这条路径的长度,即可理解为查找的时间复杂度。设当前在第i层第j列那个节点上。i) 如果第j列恰好只有i层(对应插入这个元素时第i次调用随机化模块时所产生的B决策,概率为1-p),则当前这个位置必然是从左方的某个节点向右跳过来的。ii) 如果第j列的层数大于i(对应插入这个元素时第i次调用随机化模块时所产生的A决策,概率为p),则当前这个位置必然是从上方跳下来的。(不可能从左方来,否则在以前就已经跳到当前节点上方的节点了,不会跳到当前节点左方的节点)设C(k)为向上跳

11、k层的期望步数(包括横向跳跃)有:C(0) = 0C(k) = (1-p)(1+向左跳跃之后的步数)+p(1+向上跳跃之后的步数) = (1-p)(1+C(k) + p(1+C(k-1)C(k) = 1/p + C(k-1)C(k) = k/p 而跳跃表的高度又是logn级别的,故查找的复杂度也为logn级别。对于记忆化查找(Search with fingers)技术我们可以采用类似的方法分析,很容易得出它的复杂度是O(logk)的(其中k为此次与前一次两个被查找元素在跳跃表中位置的距离)。四、插入与删除的时间复杂度分析 O(logn) 插入和删除都由查找和更新两部分构成。查找的时间复杂度为

12、O(logn),更新部分的复杂度又与跳跃表的高度成正比,即也为O(logn)。 所以,插入和删除操作的时间复杂度都为O(logn)五、实际测试效果(1)不同的p对算法复杂度的影响P平均操作时间平均列高总结点数每次查找跳跃次数(平均值)每次插入跳跃次数每次删除跳跃次数(平均值) 2/30.0024690 ms3.0049123339.87841.60441.5661/20.0020180 ms1.9956068327.80729.94729.0721/e0.0019870 ms1.5844757027.33228.23828.4521/40.0021720 ms1.3304047828.7262

13、9.47229.6641/80.0026880 ms1.1443442035.14735.82136.007表1 进行106次随机操作后的统计结果 从表1中可见,当p取1/2和1/e的时候,时间效率比较高(为什么?)。而如果在实际应用中空间要求很严格的话,那就可以考虑取稍小一些的p,如1/4。(2)运用“记忆化”查找 (Search with fingers) 的效果分析 所谓“记忆化”查找,就是在前一次查找的基础上进行进一步的查找。数据类型平均操作时间(不运用记忆化查找)平均操作时间(运用记忆化查找)平均每次查找跳跃次数(不运用记忆化查找)平均每次查找跳跃次数(运用记忆化查找)0.5随机(相

14、邻被查找元素键值差的绝对值较大)0.0020150 ms0.0020790 ms23.26226.509前后具备相关性(相邻被查找元素键值差的绝对值较小)0.0008440 ms0.0006880 ms26.1574.932表1 进行106次相关操作后的统计结果从表2中可见,当数据相邻被查找元素键值差绝对值较小的时候,我们运用“记忆化”查找的优势是很明显的,不过当数据随机化程度比较高的时候,“记忆化”查找不但不能提高效率,反而会因为跳跃次数过多而成为算法的瓶颈。合理地利用此项优化,可以在特定的情况下将算法效率提升一个层次。【跳跃表的应用】高效率的相关操作和较低的编程复杂度使得跳跃表在实际应用中

15、的范围十分广泛。尤其在那些编程时间特别紧张的情况下,高性价比的跳跃表很可能会成为你的得力助手。能运用到跳跃表的地方很多,与其去翻陈年老题,不如来个趁热打铁,拿NOI2004第一试的第一题郁闷的出纳员(Cashier)来“小试牛刀”吧。例题一:NOI2004 Day1 郁闷的出纳员(Cashier)点击查看附录中的原题 这道题解法的多样性给了我们一次对比的机会。用不同的算法和数据结构,在效率上会有怎样的差异呢? 首先定义几个变量 R 工资的范围 N 员工总数我们来看一下每一种适用的算法和数据结构的简要描述和理论复杂度:(1) 线段树简要描述:以工资为关键字构造线段树,并完成相关操作。I命令时间复

16、杂度:O(logR)A命令时间复杂度:O(1)S命令时间复杂度:F命令时间复杂度:(2) 伸展树(Splay tree)以工资为关键字构造伸展树,并通过“旋转”完成相关操作。O(logN)(3) 跳跃表(Skip List)运用跳跃表数据结构完成相关操作。 实际效果评测: (单位:秒)Test1Test2Test3Test4Test5Test6Test7Test8Test9Test10线段树0.0000.0310.0620.0940.1090.2030.2650.250伸展树0.0160.0470.1250.1410.3600.4530.422跳跃表0.1560.3680.4380.375 从

17、结果来看,线段树这种经典的数据结构似乎占据着很大的优势。可有一点万万不能忽略,那就是线段树是基于键值构造的,它受到键值范围的约束。在本题中R的范围只有105级别,这在内存较宽裕的情况下还是可以接受的。但是如果问题要求的键值范围较大,或者根本就不是整数时,线段树可就很难适应了。这时候我们就不得不考虑伸展树、跳跃表这类基于元素构造的数据结构。而从实际测试结果看,跳跃表的效率并不比伸展树差。加上编程复杂度上的优势,跳跃表尽显出其简单高效的特点。参考程序:例题二:HNOI2004 Day1 宠物收养所(pet) 此题与郁闷的出纳员最大的不同,就在于它的键值范围达到了231级别。这对线段树来说可是一大考

18、验。虽然采取边做边开空间的策略勉强可以缓解内存的压力,但此题对内存的要求很苛刻,元素相对范围来说也比较少,如果插入的元素稍微分散一些,就很有可能使得空间复杂度接近O(NlogN)!何况如果稍微拓展一下,插入的元素不是整数而是实数呢? 而这道题对于跳跃表来说,可真是再适合不过了。几乎对标准的算法不需要做修改,如果熟练的话,从思考到编写完成也就20分钟左右的时间,最终的算法效率也很高。更加重要的一点,跳跃表绝不会因键值类型的变化而失效,推广性很强。【总结】跳跃表作为一种新兴的数据结构,以相当高的效率和较低的复杂度散发着其独特的光芒。和同样以编程复杂度低而闻名的“伸展树”相比,跳跃表的效率不但不会比

19、它差,甚至优于前者(见附表1)。人们在思考一类问题的时候,往往会无意中被局限在一个小范围当中。就拿和平衡树相关的问题来说,人们凭借自己的智慧,创造出了红黑树,AVL树等一些很复杂的数据结构。可是千变万变,却一直走不出“树”这个范围。过高的编程复杂度使得这些成果很难被人们所接受。而跳跃表的出现,使得人们眼前顿时豁然开朗。原来用与树完全不相关的数据结构也能够实现树的功能!“跳跃表”这个名字有着其深远的意义。不仅是因为它形象地描述了自身的结构,更有一点,它象征着一种思考方法,一种“跳出定式”的思考方法。在你面临一个困难却山穷水复疑无路的时候,不妨找到问题的原点,“跳”出思维的定式,说不定在另一条全新

20、的路上,你将会看到胜利的曙光。【参考文献】1 William Pugh. Skip Lists: A Probabilistic Alternative to Balanced Trees2 William Pugh. A Skip List Cookbook【附录】附表:跳跃表与AVL树、2-3树、伸展树在时间效率上的对比(摘自 1 William Pugh. Skip Lists: A Probabilistic Alternative to Balanced Trees)程序:“跳跃表”的程序(Pascal语言实现):附解:为什么p=1/e的时候时间效率最高?解:由复杂度分析中得出,跳跃表的时间效率取决于跳跃的次数,也就是k/p(k为跳跃表高度),而k是级别。故有:令 x = 1/p ,则有:对求导,有当x=e时,g(x)=0,即f(x)到达极值点。此时p = 1/e 返回“实际测试效果部分”附题:NOI2004 Day1 郁闷的出纳员返回“跳跃表的应用”部分郁闷的出纳员【问题描述】OIER公司是一家大

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1