skiplist 跳转表基本概念

跳转表是一种基于概率实现的对平衡二叉树的替代数据结构,由多层有序列表组成,用于快速搜索、插入和删除操作。其核心思想是通过随机概率决定元素在上层列表的出现,实现类似于二叉树的搜索效率,但操作更高效。跳转表的搜索、插入和删除算法分别具有O(log n)的时间复杂度。
摘要由CSDN通过智能技术生成

跳转表的基本概念

跳转表是一个基于列表list的数据结构,从结构上来说,它是由多个列表组成的。各个列表在纵向形成多层,其中第一层(最底层)拥有跳转表中的所有数据节点,以上各层列表中的数据都是其底层列表的一个子集,特别地,最顶层的列表不包含任何数据,仅含有两个头尾哨兵。跳转表的结构如图所示:

skiplist_structure

用地铁站对跳转表打一个比方,设想有一个城市的地铁分为多层,其中最底层的地铁要经过该城市的所有站台;所有这些站台中,有一些人流量很密集的站台,为它们在上一层设立一条新的地铁线路,因为该线路只经过这些大站台,因此运行速度可以更快。当人们乘坐地铁的时候,为了到了某一个小站台,最快捷的方案显然是先做大站车到距离小站台最近的大站台,然后再乘坐最底层的慢车到达某个小站。跳转表就是这样一种思路,通过在上层列表节点间的快速跳转,来迅速查找到某个数据。

从上面的图中也可以看到,跳转表的结构就类似于一棵搜索树,上层列表对应了搜索树中高度较高的节点,而底层列表对应了搜索树中的叶节点。实际上,根据跳转表发明者的定义,跳转表是基于概率实现的对平衡二叉树的一种替代方案,它使用概率来实现平衡,而非强制的平衡,因而对于插入和删除节点比传统平衡树更为高效。

跳转表的结构

从宏观上来看,跳转表是由多层的列表组成的,为了实现不同层之间列表的跳转,列表中的每个节点除了要有前向后向的指针以外,还需要同时具有上下的指针,来表示不同层次地铁的“换乘路径”。为此,需要修改list的实现中关于ListNode的定义,为其增加上下的指针,即形成下面的QuadNode类型:

template <typename T>
class QuadNode{
   
public:
	T entry;
	QuadNodePosi(T) prev;
	QuadNodePosi(T) next;
	QuadNodePosi(T) above;
	QuadNodePosi(T) below;

	QuadNode() = default;
	QuadNode(T entry) :entry(entry) {
   }
};

基于QuadNode可以实现四联表QuadList类型,使用QuadList来作为跳转表的底层列表:

#define QuadNodePosi(T) QuadNode<T>*

template <typename T>
class QuadList{
   
private:
	QuadNodePosi(T) __head;
	QuadNodePosi(T) __tail;
	int             __size;

public:
	......

需要指出,每一层的列表都要是有序的,这就仿佛你在坐地铁的时候,对于任意站台,需要知道它的前一站是什么、后一站是什么,这样你才可以规划路线,并且决定在哪里下车。否则,地铁就是在各个站台之间随机运行,也就不存在我们上面所说的先坐大站车再坐小站车的策略了。为了简化操作,在初始化时应该首位哨兵的值分别为MINMAX,如下所示:

#define MAXINT (int)(0x7fffffff)
#define MININT (int)(0x80000000)

跳转表的多层次结构是通过生长概率逐层减半来实现的,具体说来,就是说在第k层出现的元素,在第k + 1层也出现的概率为p = 1 / 2。这样,如果最底层的节点数量为n,则它的上一层的期望节点数量就是n / 2,再上一层就是n / 4n / 8, ......, 2, 1,从结构上就非常类似一棵二叉树了。并且可以看出,跳转表的期望总节点数量为

n + n / 2 + n / 4 + ...... + 2 + 1 < 2n = O(n)

可见,跳转表的空间复杂度并没有因为层次的原因而得到显著增长。

跳转表的实现

跳转表的基本操作主要有三个,即搜索,插入和删除。以下就讨论如何实现这三个基本操作。

跳转表的搜索算法

实际上,在上面地铁那里已经叙述过跳转表的搜索算法了,即首先坐上层的大站车快速到达距离小站最近的位置,然后换乘底层的小站车。用算法的语言描述,即自上而下,自左而右地搜索,对于每一层的列表,从左至右遍历它的每一个元素,直到发现第一个大于搜索值key的元素,然后后退一步,如果当前节点的key值等于搜索值,则成功返回,否则表示应该在这里下车换乘了。如果当前列表还不是最底层,则切换到下一层的列表,并且重复上面的操作,直到查找成功,或者因为不存在该key值而查找失败。
这里的搜索算法将基于遵循前面列表的约定,即返回总是某一层次中不大于key值节点中的最靠右者。跳转表的搜索算法实现如下:

template <typename K, typename V>
QuadNode<entry<K, V>>* SkipList<K, V>::skipSearch(K key) {
   
	QuadNode<entry<K, V>>* qnode = 
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值