我遇到了一个有趣的问题,我对提供给我的答案感到困惑。问题如下:
The concatenation of 2 lists can be performed O(1) time.
Which of the following implementation of list should be used?
- Singly Linked List
- Doubly Linked List
- Circular Linked List
- Array Implementation Of Linked List
我最初认为DLL是正确的选择,因为连接可以从双方发生,但答案似乎是CLL。 我很迷惑。 任何解释都将是最有帮助的。 感谢。
答案 0 :(得分:7)
如果您有一个指向至少一个列表中最后一个节点的指针,则可以使用单个链表或双向链表轻松地在O(1)时间内连接两个列表。 (当然,还有指向列表的指针。)
您不能使用数组实现,因为您最终必须分配更多内存并将新结果列表复制到它。即使数组已经分配了内存,您仍然需要将所有新项目复制到它。所以它是O(m + n)或O(n)(其中m和n分别是各个列表的长度)。
使用循环链接列表,您可以在O(1)时间内轻松连接它们。这只是打破两个列表中的链接,然后将它们连接在一起的问题。当然,这假设项目的顺序并不是特别重要。
答案 1 :(得分:2)
答案是循环双重链接列表
对于列表的合并,您必须将第一个列表的最后一个节点的下一个指针指向第二个列表的第一个节点。要做到这一点 O(1)时间循环双向链表是有用的。您可以通过head1-> next-> previous转到第一个列表的最后一个节点。并修改此 指向head2-> next的字段。并且还修改head1-> next->之前的head1-> next。
如果在sinlgy和双向链表中指向任何一个列表的最后一个节点,则可以在O(1)中合并两个列表。
答案 2 :(得分:1)
似乎有多个正确答案。
只要存储指向列表的第一个和最后一个元素的指针,就可以在O(1)时间内连接两个单链接列表。您只需将第一个列表的最后一个元素的下一个指针重新连接到第二个列表的第一个元素。这也适用于双向链表。
您还可以使用类似的技巧在O(1)时间内连接两个循环链接列表。
唯一不起作用的选项是基于数组的列表。
希望这有帮助!
答案 3 :(得分:0)
您不需要last
,但确实需要next
假设每个列表至少有两个元素
void merge( node* first, node* second )
{
node * first_next = first->next;
node * second_next = second->next;
first->next = second_next;
second->next = first_next;
}
正如Jim Mischel所说,任何列表都可以正常工作。
答案 4 :(得分:0)
这两个:
是正确的答案。两者都支持O(1)连接。