人们会想到简单的代码
llist1.Last.Next = llist2.First;
llist2.First.Previous = llist1.Last;
可行,但显然在C#的LinkedList,First,Last中,它们的属性只有Get。
我能想到的另一种方法是
llist1.AddLast(llist2.First);
但是,这也不起作用 - 它失败了,因为llist2的第一个节点已经在链表中。
这是否意味着我必须有一个循环,手动AddLast的llist2的每个节点到llist1?这不会打败链表的效率????
答案 0 :(得分:16)
是的,不幸的是,你必须循环。这是一个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);
}
}
}
编辑:Erich的评论表明为什么你可能认为这是低效的 - 为什么不通过更新第一个列表的尾部的“下一个”指针和第二个列表的头部的“prev”指针将两个列表连接在一起?好吧,想想第二个列表会发生什么...... 它也会发生变化。
不仅如此,但这些节点的所有权会发生什么?现在每个都基本上是两个列表的一部分......但是LinkedListNode<T>.List
属性只能谈论其中一个。
虽然我可以在某些情况下看到为什么你可能想要这样做,但是构建.NET LinkedList<T>
类型的方式基本上禁止它。我认为这篇文档评论最能说明这一点:
LinkedList<T>)
类可以 不支持链接,分裂, 循环或其他可以的功能 将列表保持不一致 状态。
答案 1 :(得分:8)
llist1 = new LinkedList<T>(llist1.Concat(llist2));
这会连接两个列表(需要.NET 3.5)。缺点是它创建了一个新的LinkedList实例,可能不是你想要的......你可以这样做:
foreach(var item in llist2)
{
llist1.AddLast(item);
}
答案 2 :(得分:4)
在这里,您可以找到我的链表实现,其中包含O(1)concat和split times。
Why .NET LinkedList does not support Concat and Split operations?
简短摘要
与.NET LinkedList的优点:
减少内存消耗,因此SimpleLinkedListNode具有每个节点 三个指针(prev,next,value)而不是四个(prev,next,list, 值)与原始的.NET实现不同。
支持Concat和Split O(1)
支持IEnumarable Reverse()枚举器 O(1) - 顺便说一下,我没有看到为什么没有提供它的任何理由 原生在.NET LinkedList上。适当的延伸方法 需要O(n)。
缺点:
其他: