在互联网快速发展的今天,我们见证了现代数据库从结构化数据库(比如:MySQL)到 NoSQL(比如:Redis),再到大型的分布式数据库(比如:Apache Cassandra),数据库之所以可以如此快速的发展,离不开这 8种关键的数据结构,如下图:

因此,今天我们就来聊一聊这 8种数据结构。

一、Skiplist

Skip List(跳表)是一种基于链表的数据结构,用于快速查找和插入操作。它是由William Pugh于 1989 年提出的,类似于平衡二叉树,但相对于平衡二叉树而言,跳表的实现更简单且容易理解,因此它是平衡树的替代品。

原理

  1. 跳表节点结构:每个跳表节点包含一个键(key)和一个值(value),以及多个指向下一层节点的指针(forward pointers)。节点按照键的递增顺序连接在一起,形成一种层级结构。
  2. 层级结构:跳表中的节点按照层级连接,最底层是一个普通的有序链表。每个节点都有一个或多个指针指向下一层节点,这些指针称为前进指针(forward pointers)。通常,节点的层数是随机生成的,层数越高,节点在跳表中的概率越小。
  3. 查找操作:从顶层开始,逐层比较节点的键和目标键的大小,如果当前节点的下一个节点的键大于目标键,则向下一层移动。重复这个过程直到找到目标键或者无法继续向下移动为止。一般来说,查找操作的时间复杂度为O(log n)。
  4. 插入操作:插入操作需要首先执行查找操作,以找到插入位置。然后,为新节点生成一个随机的层数,将新节点插入到每一层的合适位置,并更新相关节点的前进指针。插入操作的时间复杂度也是O(log n)。
  5. 删除操作:删除操作与查找操作类似,首先执行查找操作找到待删除的节点。然后,将待删除节点从每一层中移除,并更新相关节点的前进指针。删除操作的时间复杂度也是O(log n)。

跳表通过增加多个层级和前进指针的方式,提供了一种平衡的查找和插入性能。相较于平衡二叉树,跳表的实现更简单,且不需要维护复杂的平衡条件。如下图,给出一张跳表的示例图:

优缺点

跳表的优势在于其相对简单的实现和较高的查询性能。对于有序链表的查找操作,跳表平均时间复杂度为O(log n),接近于平衡树的性能,而且在实际应用中比平衡树更加容易实现和维护。然而,跳表的插入和删除操作的平均时间复杂度较高,为O(log n),相比于链表的O(1)操作略慢。

数据库实例

在 Redis这种内存数据库中,跳表用于实现有序数据结构,例如排序集和排序列表。

二、B-tree

B-tree(平衡树)是一种常用的自平衡搜索树,广泛应用于数据库系统和文件系统等领域,用于高效地组织和管理大量有序的数据。B-tree的原理如下:

原理