0046算法笔记——【随机化算法】舍伍德随机化思想解决跳跃表问题.docx_第1页
0046算法笔记——【随机化算法】舍伍德随机化思想解决跳跃表问题.docx_第2页
0046算法笔记——【随机化算法】舍伍德随机化思想解决跳跃表问题.docx_第3页
0046算法笔记——【随机化算法】舍伍德随机化思想解决跳跃表问题.docx_第4页
0046算法笔记——【随机化算法】舍伍德随机化思想解决跳跃表问题.docx_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

问题描述 如果用有序链表来表示一个含有n个元素的有序集S,则在最坏情况下,搜索S中一个元素需要O(n)计算时间。提高有序链表效率的一个技巧是在有序链表的部分结点处增设附加指针以提高其搜索性能。在增设附加指针的有序链表中搜索一个元素时,可借助于附加指针跳过链表中若干结点,加快搜索速度。这种增加了向前附加指针的有序链表称为跳跃表。 应在跳跃表的哪些结点增加附加指针以及在该结点处应增加多少指针完全采用随机化方法来确定。这使得跳跃表可在O(logn)平均时间内支持关于有序集的搜索、插入和删除等运算。 例如:如图,(a)是一个没有附加指针的有序表,而图(b)在图(a)的基础上增加了跳跃一个节点的附加指针。图(c)在图(b)的基础上又增加了跳跃3个节点的附加指针。 在跳跃表中,如果一个节点有k+1个指针,则称此节点为一个k级节点。以图(c)中跳跃表为例,看如何在改跳跃表中搜索元素8。从该跳跃表的最高级,即第2级开始搜索。利用2级指针发现元素8位于节点7和19之间。此时在节点7处降至1级指针进行搜索,发现元素8位于节点7和13之间。最后,在节点7降至0级指针进行搜索,发现元素8位于节点7和11之间,从而知道元素8不在搜索的集合S中。 相关原理 在一般情况下,给定一个含有n个元素的有序链表,可以将它改造成一个完全跳跃表,使得每一个k级结点含有k+1个指针,分别跳过2k-1,2(k-1)-1,20-1个中间结点。第i个k级结点安排在跳跃表的位置i2k处,i=0。这样就可以在时间O(logn)内完成集合成员的搜索运算。在一个完全跳跃表中,最高级的结点是级结点。 完全跳跃表与完全二叉搜索树的情形非常类似。它虽然可以有效地支持成员搜索运算,但不适应于集合动态变化的情况。集合元素的插入和删除运算会破坏完全跳跃表原有的平衡状态,影响后继元素搜索的效率。 为了在动态变化中维持跳跃表中附加指针的平衡性,必须使跳跃表中k级结点数维持在总结点数的一定比例范围内。注意到在一个完全跳跃表中,50%的指针是0级指针;25%的指针是1级指针;(100/2(k+1)%的指针是k级指针。因此,在插入一个元素时,以概率1/2引入一个0级结点,以概率1/4引入一个1级结点,以概率1/2(k+1)引入一个k级结点。另一方面,一个i级结点指向下一个同级或更高级的结点,它所跳过的结点数不再准确地维持在2i-1。经过这样的修改,就可以在插入或删除一个元素时,通过对跳跃表的局部修改来维持其平衡性。 跳跃表中节点的级别在插入是确定,一旦确定便不再更改。下图是遵循上述原则的跳跃表的例子。对其进行搜索与对完全跳跃表所作的搜索是一样的。如果希望在所示跳跃表中插入一个元素8,则应现在跳跃表中搜索其插入位置。经搜索发现应在节点7和11之间插入元素8.此时在节点7和11之间增加1个存储元素8的新节点,并以随机的方式确定新节点的级别。例如,如果元素8是作为一个2级节点插入,则应对图中虚线相交的指针进行调整,如果新插入的节点是一个1级节点,则只要修改2个指针,虚线相交的指针是有可能被修改的指针,这些指针可在搜索元素插入位置时动态地保存起来,以供插入时使用。 在一个完全跳跃表中,具有i级指针的结点中有一半同时具有i+1级指针。为了维持跳跃表的平衡性,可以事先确定一个实数0p1,并要求在跳跃表中维持在具有i级指针的结点中同时具有i+1级指针的结点所占比例约为p。为此目的,在插入一个新结点时,先将其结点级别初始化为0,然后用随机数生成器反复地产生一个0,1间的随机实数q。如果q=p。由此产生新结点级别的过程可知,所产生的新结点的级别为0的概率为1-p,级别为1的概率为p(1-p),级别为i的概率为pi(1-p)。如此产生的新结点的级别有可能是一个很大的数,甚至远远超过表中元素的个数。为了避免这种情况,用作为新结点级别的上界。其中n是当前跳跃表中结点个数。当前跳跃表中任一结点的级别不超过。 算法具体实现如下: 1、RandomNumber.hcppview plaincopy1. #includetime.h2. /随机数类3. constunsignedlongmaxshort=65536L;4. constunsignedlongmultiplier=1194211693L;5. constunsignedlongadder=12345L;6. 7. classRandomNumber8. 9. private:10. /当前种子11. unsignedlongrandSeed;12. public:13. RandomNumber(unsignedlongs=0);/构造函数,默认值0表示由系统自动产生种子14. unsignedshortRandom(unsignedlongn);/产生0:n-1之间的随机整数15. doublefRandom(void);/产生0,1)之间的随机实数16. ;17. 18. RandomNumber:RandomNumber(unsignedlongs)/产生种子19. 20. if(s=0)21. 22. randSeed=time(0);/用系统时间产生种子23. 24. else25. 26. randSeed=s;/由用户提供种子27. 28. 29. 30. unsignedshortRandomNumber:Random(unsignedlongn)/产生0:n-1之间的随机整数31. 32. randSeed=multiplier*randSeed+adder;/线性同余式33. return(unsignedshort)(randSeed16)%n);34. 35. 36. doubleRandomNumber:fRandom(void)/产生0,1)之间的随机实数37. 38. returnRandom(maxshort)/double(maxshort);39. 2、7d3d3.cppcppview plaincopy1. /随机化算法跳跃表2. #includestdafx.h3. #includeRandomNumber.h4. #include5. #include6. usingnamespacestd;7. 8. templateclassSkipList;9. template10. classSkipNode11. 12. friendSkipList;13. private:14. SkipNode(intsize)15. 16. next=newSkipNode*size;17. 18. SkipNode()19. 20. deletenext;21. 22. ETypedata;/集合中的元素23. SkipNode*next;/指针数组nexti是第i级指针24. ;25. 26. template27. classSkipList28. 29. public:30. SkipList(KTypeLarge,intMaxE=10000,floatp=0.5);31. SkipList();32. boolSearch(constKType&k,EType&e)const;33. SkipList&Insert(constEType&e);34. SkipList&Delete(constKType&k,EType&e);35. voidOutput();36. private:37. intLevel();38. SkipNode*SaveSearch(constKType&k);39. intMaxLevel;/跳跃表级别上界40. intLevels;/当前最大级别41. RandomNumberrnd;/随机数产生器42. floatProb;/用于分配节点级别43. KTypeTailKey;/元素键值上界44. SkipNode*head;/头结点指针45. SkipNode*NIL;/尾节点指针46. SkipNode*last;/指针数组47. ;48. 49. /构造函数50. template51. SkipList:SkipList(KTypeLarge,intMaxE,floatp)52. 53. Prob=p;54. MaxLevel=ceil(log(float(MaxE)/log(1/p)-1;/初始化跳跃表级别上界55. TailKey=Large;/元素键值上界56. Levels=0;/初始化当前最大级别57. 58. /创建头、尾节点和数组last59. head=newSkipNode(MaxLevel+1);60. NIL=newSkipNode(0);61. last=newSkipNode*MaxLevel+1;62. NIL-data=Large;63. 64. /将跳跃表初始化为空表65. for(inti=0;inexti=NIL;68. 69. 70. 71. /析构函数72. template73. SkipList:SkipList()74. 75. SkipNode*next;76. 77. /删除所有节点78. while(head!=NIL)79. 80. next=head-next0;81. deletehead;82. head=next;83. 84. 85. deleteNIL;86. deletelast;87. 88. 89. classelement90. 91. friendintmain(void);92. public:93. operatorlong()const94. 95. returnkey;96. 97. element&operator=(longy)98. 99. key=y;100. return*this;101. 102. private:103. intdata;104. longkey;105. ;106. 107. /搜索指定元素k108. template109. boolSkipList:Search(constKType&k,EType&e)const110. 111. if(k=TailKey)112. 113. returnfalse;114. 115. /位置p恰好位于指定元素k之前116. SkipNode*p=head;117. for(inti=Levels;i=0;i-)/逐渐向下搜索118. 119. while(p-nexti-datanexti;/每次搜索尽可能滴接近要搜索的元素122. 123. 124. e=p-next0-data;125. return(e=k);126. 127. 128. /搜索指定元素k,并将每一级中遇到的上一个节点存放在数组last中129. template130. SkipNode*SkipList:SaveSearch(constKType&k)131. 132. /位置p恰好位于指定元素k之前133. SkipNode*p=head;134. for(inti=Levels;i=0;i-)135. 136. while(p-nexti-datanexti;139. 140. lasti=p;/上一个第i级结点141. 142. return(p-next0);143. 144. 145. /产生不超过MaxLevel的随机级别146. template147. intSkipList:Level()148. 149. intlev=0;150. while(rnd.fRandom()Prob)151. 152. lev+;153. 154. return(lev=MaxLevel)?lev:MaxLevel;155. 156. 157. /插入指定元素e158. template159. SkipList&SkipList:Insert(constEType&e)160. 161. KTypek=e;/取得元素键值162. if(k=TailKey)163. 164. cout元素键值超界!endl;165. return*this;166. 167. /检查元素是否已存在168. SkipNode*p=SaveSearch(k);169. if(p-data=e)170. 171. cout元素已存在!Levels)179. 180. for(inti=Levels+1;i=lev;i+)181. 182. lasti=head;183. 184. Levels=lev;185. 186. 187. /产生新节点,并将新节点插入p之后188. SkipNode*y=newSkipNode(lev+1);189. y-data=e;190. 191. for(inti=0;inexti=lasti-nexti;195. lasti-nexti=y;196. 197. return*this;198. 199. 200. /删除键值为k的元素,并将所删除的元素存入e201. template202. SkipList&SkipList:Delete(constKType&k,EType&e)203. 204. if(k=TailKey)205. 206. cout元素键值超界!endl;207. 208. /搜索待删除元素209. SkipNode*p=SaveSearch(k);210. if(p-data!=k)211. 212. cout未找到待删除元素!endl;213. 214. /从跳跃表中删除节点215. for(inti=0;inexti=p;i+)216. 217. lasti-nexti=p-nexti;218. 219. /更新当前级别220. while(Levels0&head-nextLevels=NIL)221. 222. Levels-;223. 224. e=p-

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论