如何在 C# 中将 LinkedList<T> 添加到 LinkedList<T>?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1094445/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does one add a LinkedList<T> to a LinkedList<T> in C#?
提问by
One would think the simple code
人们会认为简单的代码
llist1.Last.Next = llist2.First;
llist2.First.Previous = llist1.Last;
would work, however apparently in C#'s LinkedList, First, Last, and their properties are Get only.
会起作用,但显然在 C# 的 LinkedList、First、Last 中,并且它们的属性仅为 Get。
The other method I could think of was
我能想到的另一种方法是
llist1.AddLast(llist2.First);
However, this does not work either - it fails because the first node of llist2 is already in a linked list.
但是,这也不起作用——它失败了,因为 llist2 的第一个节点已经在一个链表中。
Does this mean that I have to have a loop that manually AddLast's each node of llist2 to llist1? Doesn't this defeat the efficiency of linked lists????
这是否意味着我必须有一个循环将 llist2 的每个节点手动 AddLast 到 llist1?这不会破坏链表的效率吗????
回答by Thomas Levesque
llist1 = new LinkedList<T>(llist1.Concat(llist2));
this concatenates the two lists (requires .NET 3.5). The drawback is that it creates a new instance of LinkedList, which may not be what you want... You could do something like that instead :
这将连接两个列表(需要 .NET 3.5)。缺点是它创建了一个新的 LinkedList 实例,这可能不是你想要的......你可以这样做:
foreach(var item in llist2)
{
llist1.AddLast(item);
}
回答by Jon Skeet
Yes, you have to loop, unfortunately. This is an O(n) operation - O(1) for each entry added. There's no risk of requiring a buffer to be resized and copied, etc - although of course garbage collection might do roughly that :) You could even write handy extension methods:
是的,不幸的是,您必须循环。这是一个 O(n) 操作 - 对于添加的每个条目 O(1)。没有需要调整缓冲区大小和复制等的风险 - 尽管垃圾收集当然可能会做粗略的 :) 您甚至可以编写方便的扩展方法:
public static class LinkedListExtensions
{
public static void AppendRange<T>(this LinkedList<T> source,
IEnumerable<T> items)
{
foreach (T item in items)
{
source.AddLast(item);
}
}
public static void PrependRange<T>(this LinkedList<T> source,
IEnumerable<T> items)
{
LinkedListNode<T> first = source.First;
foreach (T item in items)
{
source.AddBefore(first, item);
}
}
}
EDIT: Erich's comment suggests why you might think this is inefficient - why not just join the two lists together by updating the "next" pointer of the tail of the first list and the "prev" pointer of the head of the second? Well, think about what would happen to the second list... itwould have changed as well.
编辑:Erich 的评论表明为什么您可能认为这是低效的 - 为什么不通过更新第一个列表尾部的“next”指针和第二个列表头部的“prev”指针将两个列表连接在一起?好吧,想想第二个列表会发生什么……它也会改变。
Not only that, but what would happen to the ownership of those nodes? Each is essentially part of two lists now... but the LinkedListNode<T>.List
property can only talk about one of them.
不仅如此,这些节点的所有权会怎样?现在每个基本上都是两个列表的一部分......但该LinkedListNode<T>.List
属性只能谈论其中一个。
While I can see why you might want to do this in some cases, the way that the .NET LinkedList<T>
type has been built basically prohibits it. I think this doc comment explains it best:
虽然我可以理解为什么在某些情况下您可能想要这样做,但 .NETLinkedList<T>
类型的构建方式基本上禁止它。我认为这个文档评论最好地解释了它:
The
LinkedList<T>)
class does not support chaining, splitting, cycles, or other features that can leave the list in an inconsistent state.
本
LinkedList<T>)
类不支持链接,分裂,周期,或其他功能,可以留在不一致的状态列表。
回答by George Mamaladze
Here you can find my linked list implementation with O(1) concat and split times.
在这里你可以找到我的链表实现,它的连接和拆分时间为 O(1)。
Why .NET LinkedList does not support Concat and Split operations?
为什么 .NET LinkedList 不支持 Concat 和 Split 操作?
Short summary
简短的摘要
Advantages vs .NET LinkedList:
与 .NET LinkedList 相比的优势:
Less memory consumption, thus every node SimpleLinkedListNode has three pointers (prev, next, value) instead of four (prev, next, list, value) unlike original .NET implementation.
Supports Concat and Split operations in O(1)
Supports IEnumarable Reverse() enumerator in O(1) – by the way I do not see any reason why it's not provided natively on the .NET LinkedList. Appropriate extension method requires O(n).
更少的内存消耗,因此与原始 .NET 实现不同,每个节点 SimpleLinkedListNode 都有三个指针(prev、next、value)而不是四个(prev、next、list、value)。
支持 O(1) 中的 Concat 和 Split 操作
支持 O(1) 中的 IEnumarable Reverse() 枚举器 - 顺便说一下,我没有看到任何原因为什么它没有在 .NET LinkedList 上本地提供。适当的扩展方法需要 O(n)。
Disadvantages:
缺点:
- Does not support Count.
- Concat operation leaves second list in an inconsistent state.
- Split operation leaves original list in an inconsistent state.
- You are able to share nodes between lists.
- 不支持计数。
- Concat 操作使第二个列表处于不一致状态。
- 拆分操作使原始列表处于不一致状态。
- 您可以在列表之间共享节点。
Other:
其他:
- I have chosen an alternative strategy for implementing enumeration and find operations, rather than more verbose and purely readable original implementation. I hope the negative performance impact remains insignificant.
- 我选择了一种替代策略来实现枚举和查找操作,而不是更冗长和纯粹可读的原始实现。我希望负面性能影响仍然微不足道。