红黑树的反思以及跳表的学习

5 阅读3分钟

经过一周多时间的红黑树的深入学习,终于明白了以我初学者的身份压根没有任何必要进入那个深水区,我现在最重要的是往广度方向学习。再加上今天一整天对跳表的深入的思考以后,我终于有点理解了工程化的思维跟纯理论思维的巨大差异。从最开始了解了跳表的一些理论以后自己就一直在想这个跳表我自己写的话应该怎么做,思考的过程中终于对内存有了较深的理解不再仅仅是new个对象,一个class文件,方法区,堆内存,栈内存这些概念性的东西。 想了很久以后也想到了应该按size的2的幂去进行上抛策略,在原基础上进行上抛。但是跟元宝聊了很久以后发现源码压根不是按这个策略去设计的,源码的设计是每个节点都会进行32次随机数判断然后选择是否上抛,并且不会覆盖原节点。这样的话上层就会变成一个存储节点的列表。我也困惑过这玩意能做到log(n)吗?因为概率都是一样的,假如32层就是root那不就炸了?但是元宝说期望值是log(n),我高中数学也忘干净了,也就知道一点概念而已。但是工程上确实能做到log(n)的效率,其实我还是不太理解。尽管每层都会有一些节点存在,但是假如这个跳表的第32层就只有2个节点第二个节点就是root咋办?那查询不就永远是O(n)了么。我也懒得纠结这个玩意了,因为已经吃过红黑树的亏了,不敢再进去那个深水区试探了。现在的我选择默认接受,我就开始想我如果动手写这个跳表应该怎么写,我最开始想到的就是在这个跳表类中定义一个32层的动态数组,我这样想完以后就觉得这玩意也过于低级了点。我就找元宝验证,果然源码没有用这么低级的设计,元宝告诉我的是源码用的策略是节点自带一个自身定位层级的数组,我就恍然大悟了,也感受到了源码的牛逼之处了。本来最开始接触跳表的时候我就被这个设计就已经震惊过了,结果对于节点自定位的设计更加震惊,现在的我只能顶礼膜拜,这些设计者我除了说牛逼也不知道再用什么词语形容了。现在应该也勉强能开始动笔写点代码了,尽管我相信看源码思路直接学习的效率可能会更快,但是我还想继续用这种自己推导的方式去学习这些经典容器。因为我觉得这样学习才能真正感受到作者的设计的精妙之处,自己在以后的码农生活应该也会更加容易想到怎么运用这些作者的设计思路。