一、什么是跳表
跳表为一个值有序的链表建立多级索引;比如每2个节点提取一个节点到时上一级,我们把抽出来的那一级叫做索引或索引层。
二、跳表的时间复杂度?
1、计算跳表的高度
如果链表有n个节点,每2个节点抽取一个节点作为上一级索引的节点,那第一级的节点个数大约是n/2,第二级索引则是在第一级索引上每2个节点抽取一个节点则它的节点个数大约是n/4,依次类推,第k级索引的节点个数就是n/(2^k)。假设索引有h级别,最高级的索引有2个节点,则有n/(2^h)=2,那么h=log2n-1,包含原始链表这一层,整个跳表的高度就是log2n。
2、计算跳表的时间复杂度
假设我们在跳表中查询某个数据的时候,如果每一层都遍历m个节点,那在跳表中查询一个数据的时间复杂度就是O(m*logn)。因为索引与它下面一层索引相差个2元素,包括自己只有3个元素,所以m最大为3。所有复杂度就是O(logn)。
三、跳表的空间复杂度及如何优化?
1、计算索引的节点总数
如果链表有n个节点,每2个节点抽取抽出一个节点作为上一级索引的节点,那每一级索引的节点数分别为:n/2,n/4,n/8,..,8,4,2,等比数列求和等于n-1,所以跳表的空间复杂度为O(n)。
2、如何优化空间复杂度
如果链表有n个节点,每3或5个节点抽取抽出一个节点作为上一级索引的节点,那每一级索引的节点数分别为(以3为列):n/3,n/9,n/27...,9,3,1,等比数列求和等于n/2,尽管空间复杂度还是 O(n),但比上面的每两个结点抽一个结点的索引构建方法,要减少了一半的索引结点存储空间。
四、高效的动态插入和删除?
跳表本质上就是链表,所以公插入和删除操作时间复杂度为O(1),但是在实际情况中,插入或删除某个节点,需要先找到指定位置,而这个 查找操作比较费时,但在跳表中这个 查找操作的时间复杂度是O(logn),所以,跳表的插入和删除操作的时间复杂度也是O(logn)。
五、跳表索引动态更新?
当往跳表插入数据的时候,可以选择同时将这个数据插入到部分索引层中,那么如何选择这个索引层呢?可以通过随时函数来决定将这个节点插入到哪几级索引中,比如随机函数生成了值k,那就可以把这个节点添加到第1级到时第k级索引中。
六、java实现跳表需注意
1、每次插入数据的时候随机产生的level:决定了新节点的层数;
2、数组update的作用:用以存储新节点所有层数上,各自的前一个节点的信息;
3、节点内的forwards数组:用以存储该节点所有层的下一个节点的信息;
4、当所有节点的最大层级变量maxlevel=1的时候,跳表退化成一个普通链表