我们可以比O(n)时间更好地搜索排序的链表吗?
排序链表的最坏情况搜索时间为O(n),因为我们只能线性遍历链表,而在搜索时不能跳过节点。对于平衡二进制搜索树,在与根进行一次比较之后,我们跳过了几乎一半的节点。对于排序的数组,我们具有随机访问权限,可以对数组应用二进制搜索。
我们可以扩充排序的链表以使搜索更快吗?答案是跳过列表。这个想法很简单,我们创建了多个层,以便我们可以跳过一些节点。请参见下面的示例列表,其中包含16个节点和两个图层。上层用作仅连接主要外部站点的“特快车道”,而下层则用作连接每个站点的“普通车道”。假设我们要搜索50,我们从“ express lane”的第一个节点开始,继续沿“ express lane”移动,直到找到下一个大于50的节点。一旦找到这样的节点(30是在下面的示例中),在“快车道”上,我们使用该节点的指针移至“正常车道”,并在“正常车道”上线性搜索50。在下面的示例中,我们从“正常车道”上的30开始,通过线性搜索,我们找到50。
两层的时间复杂度是多少?最坏的情况是时间复杂度是“正常车道”上的“快速车道”上的节点数量加上一个分段(一个分段是两个“快速车道”节点之间的“正常车道”节点的数量)的数量。因此,如果我们在“常规车道”上有n个节点,在“表达车道”上有√ n个节点(n的平方根),并且均等地划分了“正常车道”,则“正常车道”。   n实际上是具有两层的最佳除法。通过这种布置,遍历用于搜索的节点的数量将是O(√ n)。因此,使用O(√ n)额外的空间,我们可以将时间复杂度降低到O(√ n)。
我们可以做得更好吗?
通过添加更多层,可以进一步降低跳过列表的时间复杂度。实际上,在平均情况下,具有O(n)额外空间的情况下,搜索,插入和删除的时间复杂度可能变为O(Logn)。我们很快将在“跳过列表”上发布更多帖子。
参考
麻省理工学院关于跳过列表的视频讲座
http://en.wikipedia.org/wiki/Skip_list