【问题标题】:Ideal Skip list ? O(n) run-time?理想的跳过列表? O(n) 运行时间?
【发布时间】:2012-04-28 18:51:10
【问题描述】:

我正在尝试为

找到最佳算法
converting an "ordinary" linked list 
into an `ideal skip list`

ideal skip list 的定义是在第一级我们将拥有所有 元素,在它们的一半以上的水平,它们的后四分之一......等等。

我正在考虑 O(n) 运行时,其中涉及为每个节点扔硬币 原始链表,无论是否针对特定节点,我是否应该上去,并为楼上的当前节点创建另一个重复节点... 最终这个算法会产生 O(n) ,有没有更好的算法?

问候

【问题讨论】:

  • 请参阅wiki page 了解您提到的随机算法

标签: algorithm linked-list skip-lists


【解决方案1】:

我假设链表已排序 - 否则无法在基于比较的算法中完成,因为您需要在 Omega(nlogn) 中对其进行排序

  • 迭代列表的“最高级别”,每隔一个节点添加一个“链接节点”。
  • 重复直到最高层只有一个节点。

这个想法是生成一个新列表,大小是原始列表的一半,在每个第二个链接中链接到原始列表,然后在较小的列表上递归调用,直到达到大小为 1 的列表。
您最终会得到相互链接的大小为 1、2、4、...、n/2 的列表。

伪代码:

makeSkipList(list):
  if (list == null || list.next == null): //stop clause - a list of size 1
      return
//root is the next level list, which will have n/2 elements.
  root <- new link node
  root.linkedNode <- list //linked node is linking "down" in the skip list.
  root.next <- null //next is linking "right" in the skip list.
  lastLinkNode <- root
  i <- 1
//we create a link every second element
  for each node in list, exlude the first element:
     if (i++ %2 == 0): //for every 2nd element, create a link node.
         lastLinkNode.next <- new link node 
         lastLinkNode <- lastLinkNode.next //setting the "down" field to the element in the list
         lastLinkNode.linkedNode <- node 
         lastLinkNode.next <- null
   makeSkipList(root) //recursively invoke on the new list, which is of size n/2.

复杂度为 O(n),因为算法复杂度可以描述为T(n) = n + T(n/2),因此你得到T(n) = n + n/2 + n/4 + ... -&gt; 2n

很容易看出它不能比O(n)做得更好,因为至少你必须在原始列表的后半部分添加至少一个节点,而到达那里本身就是O(n)

【讨论】:

  • “最高级别”是什么意思?我从第 0 级(完整的原始链表)开始,然后我在第一个节点之后取一个,即我在“头”之后取和节点,然后我上楼为它放置一个新节点,楼上?你的算法对我来说不是很清楚......你能解释一下吗?
  • @ron:我编辑了答案并添加了一个描述递归函数的注释伪代码,想法是 - 为您的大小为 n/2 的跳过列表创建一个链接,然后递归调用您较小的列表,直到你得到一个大小为 1 的列表,你最终会得到大小为: 1, 2, 4, .... , n/2, n 的列表
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 2023-03-23
  • 1970-01-01
相关资源
最近更新 更多