使用指针约束有效地在双向链表中搜索值?

时间:2014-04-12 21:07:58

标签: algorithm data-structures linked-list time-complexity

我已经解决了这个问题:

  

假设您有一个双向链表和一个指向该列表中某个元素的指针。假设你想要在列表中搜索某个值v,你知道它存在于某个地方。除了p之外不使用指针,设计用于查找v的Θ(m)-time算法,其中m是p与包含v的节点之间的距离。不要修改输入列表。

有没有人有任何想法如何解决这个问题?我能想到的唯一方法是破坏性地修改列表。

2 个答案:

答案 0 :(得分:5)

作为提示:如果向前迈出一步,向后退两步,向前退步四步,退回八步等,会发生什么?找到元素需要多少步骤?

进行分析时,您可能会发现总结几何系列很有用。如果有帮助,1 + r + r 2 + r 3 + ... + r n-1 =(r n - 1)/(r - 1)。

希望这有帮助!

答案 1 :(得分:4)

我认为templatetypedef has the correct answer,但根据问题的原始措辞,我想到了以下解决方案,该问题表明该列表无法被销毁或改组#34;这可能意味着修改它是可以的,如果你可以再次改变它 - 即使这不是真的,我仍然认为这是一个有趣的方法。


可以用2个指针轻松解决,对吗?一个前进,一个返回,同时移动两个,直到你找到你想要的价值。

现在这一切都很好,除了我们只允许有1个指针。

如果考虑双链表,我们知道前一个节点的next指针只是指向当前元素的指针,所以,如果我们丢失它,我们就可以再次设置它。

所以我们可以使用p.prev.next作为免费存储空间(和p.prev.prev.next一样,给出类似的参数)。

所以,我们只能使用一个指针前进,然后将一个指针存储在p.prev.next中,并在我们进行时适当地移动它。

一些Java-esque伪代码忽略了列表末尾检查而没有简单地找到它(我认为它已经足够复杂了):

if p.data == v
  return v

p = p.next
p.prev.next = p.prev.prev

while not found
  if p == v || p.prev.next == v
    p.prev.next = p                   // restore p.prev.next
    return v
  p = p.next
  p.prev.next = p.prev.prev.next.prev // set up p.prev.next from p.prev.prev.next
  p.prev.prev.next = p.prev           // restore p.prev.prev.next