反转双向链表的子列表

时间:2015-12-07 11:12:58

标签: algorithm reverse doubly-linked-list

我最近提出了一个问题,并且通过一些阅读我理解有一种方法可以在恒定时间内反转双向链表,只需交换头尾指针即可。

现在,考虑到问题的略有不同的版本,如果我们想要反转双向链表的子列表(从x到y),怎么可能呢?

0->1->2->3->4->5->6->7->8->9 with(x = 2, y = 7) 会成为: 0->1->7->6->5->4->3->2->8->9

2 个答案:

答案 0 :(得分:2)

你可以但是你可以搞乱链表。 基本上我们向每个节点添加一个位,说明此时是否应该反转顺序。 接下来,您将迭代器修改为xor到目前为止看到的所有这些新位。

迭代器现在将根据位的xor选择next / prev或prev / next。

现在你可以在O(1)中反转链表中的任意间隔,但是你失去了迭代器的一致性:任何交换操作都可能使现有的迭代器无效。此外,代码将非常混乱,所以如果可能的话我会避免它。

要进行实际翻转,请更改(添加空检查以确保不会崩溃)

 (first->prev,last->next) = (last->next, first->prev)
 last->next->next = last
 first->prev->prev = first
 last.reverse_here = !last.reverse_here
 first->prev.reverse_here = !first->prev.reverse_here
 Invalidate_all_existing_iterators()

在纸上画画,因为它很混乱。

答案 1 :(得分:0)

way to reverse a doubly linked list in constant time

这是不可能的,但是在线性时间O(n)

中是可能的

回答问题:你必须以不同于其他方式管理“开始”和“结束”。如果你从7开始并转到2,你会记住这个指针7->将它存储在变量X中。它将指针存储到8.然后你像往常一样继续。

当你达到2时,你把2.head = X。

对于1-> 7,必须做类似的事情,但你应该弄清楚。

编辑常量时间:您可以在恒定时间内重写迭代器,但数据结构本身保持不变。因此,只改变迭代器,你不能自己反转数据并用它做一些事情 - 因为它并没有真正逆转。

PS:在arraylist中,即使是子列表,也可以在常量时间内更改迭代器。