理想的跳过清单? O(n)运行时间?

时间:2012-04-28 18:51:11

标签: algorithm linked-list skip-lists

我正在努力寻找

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

ideal skip list的定义是第一级的定义,我们将拥有全部 这些元素,在其上半部分,其中一部分之后......等等。

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

问候

1 个答案:

答案 0 :(得分: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 + ... -> 2n

很容易看出它不能比O(n)做得更好,因为至少你必须在原始列表的后半部分添加至少一个节点,并且自己实现{{} 1}}