Loading docs/ds/skiplist.md +4 −4 Original line number Diff line number Diff line Loading @@ -10,9 +10,11 @@ 一个有序链表的查找操作,就是从头部开始逐个比较,直到当前节点的值大于或者等于目标节点的值。很明显,这个操作的复杂度是 $O(n)$ 。 跳表在有序链表的基础上,引入了 **分层** 的概念。首先,跳表的每一层都是一个有序链表,特别地,最底层是初始的有序链表。每个位于第 $i$ 层的节点有 $p$ 的概率出现在第 $i+1$ 层, $p$ 为常数。可以计算出,跳表的期望层数为 $\log_{\frac{1}{p}}n$ 。 跳表在有序链表的基础上,引入了 **分层** 的概念。首先,跳表的每一层都是一个有序链表,特别地,最底层是初始的有序链表。每个位于第 $i$ 层的节点有 $p$ 的概率出现在第 $i+1$ 层, $p$ 为常数。 在跳表中查找,就是从最高层开始,水平地逐个比较,直至当前节点大于等于目标节点。若是当前节点等于目标节点,则成功查找;若是大于目标节点或者是达到链表的末尾,就退回上一个元素后下降到下一层,直到找到目标节点或者达到最底层的末尾。这样一来,查找的过程中会跳过一些没有必要的比较,所以相比于有序链表的查询,跳表的查询更快。可以证明,跳表查询的平均复杂度为 $O(\log n)$ 。 记在 n 个节点的跳表中,期望包含 $\frac{1}{p}$ 个元素的层为第 $L(n)$ 层,易得 $L(n) = \log_{\frac{1}{p}}n$ 。 在跳表中查找,就是从第 $L(n)$ 层开始,水平地逐个比较直至当前节点的下一个节点大于等于目标节点,然后移动至下一层。重复这个过程直至到达第一层且无法继续进行操作。此时,若下一个节点是目标节点,则成功查找;反之,则元素不存在。这样一来,查找的过程中会跳过一些没有必要的比较,所以相比于有序链表的查询,跳表的查询更快。可以证明,跳表查询的平均复杂度为 $O(\log n)$ 。 ## 复杂度证明 Loading @@ -24,8 +26,6 @@ ### 时间复杂度 记 n 个节点的跳表的期望层数为 $L(n)$ 。 从后向前分析查找路径,这个过程可以分为从最底层爬到第 $L(n)$ 层和后续操作两个部分。在分析时,假设一个节点的具体信息在它被访问之前是未知的。 假设当前我们处于一个第 $i$ 层的节点 $x$ ,我们并不知道 $x$ 的最大层数和 $x$ 左侧节点的最大层数,只知道 $x$ 的最大层数至少为 $i$ 。如果 $x$ 的最大层数大于 $i$ ,那么下一步应该是向上走,这种情况的概率为 $p$ ;如果 $x$ 的最大层数等于 $i$ ,那么下一步应该是向左走,这种情况概率为 $1-p$ 。 Loading Loading
docs/ds/skiplist.md +4 −4 Original line number Diff line number Diff line Loading @@ -10,9 +10,11 @@ 一个有序链表的查找操作,就是从头部开始逐个比较,直到当前节点的值大于或者等于目标节点的值。很明显,这个操作的复杂度是 $O(n)$ 。 跳表在有序链表的基础上,引入了 **分层** 的概念。首先,跳表的每一层都是一个有序链表,特别地,最底层是初始的有序链表。每个位于第 $i$ 层的节点有 $p$ 的概率出现在第 $i+1$ 层, $p$ 为常数。可以计算出,跳表的期望层数为 $\log_{\frac{1}{p}}n$ 。 跳表在有序链表的基础上,引入了 **分层** 的概念。首先,跳表的每一层都是一个有序链表,特别地,最底层是初始的有序链表。每个位于第 $i$ 层的节点有 $p$ 的概率出现在第 $i+1$ 层, $p$ 为常数。 在跳表中查找,就是从最高层开始,水平地逐个比较,直至当前节点大于等于目标节点。若是当前节点等于目标节点,则成功查找;若是大于目标节点或者是达到链表的末尾,就退回上一个元素后下降到下一层,直到找到目标节点或者达到最底层的末尾。这样一来,查找的过程中会跳过一些没有必要的比较,所以相比于有序链表的查询,跳表的查询更快。可以证明,跳表查询的平均复杂度为 $O(\log n)$ 。 记在 n 个节点的跳表中,期望包含 $\frac{1}{p}$ 个元素的层为第 $L(n)$ 层,易得 $L(n) = \log_{\frac{1}{p}}n$ 。 在跳表中查找,就是从第 $L(n)$ 层开始,水平地逐个比较直至当前节点的下一个节点大于等于目标节点,然后移动至下一层。重复这个过程直至到达第一层且无法继续进行操作。此时,若下一个节点是目标节点,则成功查找;反之,则元素不存在。这样一来,查找的过程中会跳过一些没有必要的比较,所以相比于有序链表的查询,跳表的查询更快。可以证明,跳表查询的平均复杂度为 $O(\log n)$ 。 ## 复杂度证明 Loading @@ -24,8 +26,6 @@ ### 时间复杂度 记 n 个节点的跳表的期望层数为 $L(n)$ 。 从后向前分析查找路径,这个过程可以分为从最底层爬到第 $L(n)$ 层和后续操作两个部分。在分析时,假设一个节点的具体信息在它被访问之前是未知的。 假设当前我们处于一个第 $i$ 层的节点 $x$ ,我们并不知道 $x$ 的最大层数和 $x$ 左侧节点的最大层数,只知道 $x$ 的最大层数至少为 $i$ 。如果 $x$ 的最大层数大于 $i$ ,那么下一步应该是向上走,这种情况的概率为 $p$ ;如果 $x$ 的最大层数等于 $i$ ,那么下一步应该是向左走,这种情况概率为 $1-p$ 。 Loading