如何在C#中将链接列表<t>添加到链接列表<t>?</t> </t>

时间:2009-07-07 19:49:54

标签: c# .net list linked-list

人们会想到简单的代码

llist1.Last.Next = llist2.First;
llist2.First.Previous = llist1.Last;

可行,但显然在C#的LinkedList,First,Last中,它们的属性只有Get。

我能想到的另一种方法是

llist1.AddLast(llist2.First);

但是,这也不起作用 - 它失败了,因为llist2的第一个节点已经在链表中。

这是否意味着我必须有一个循环,手动AddLast的llist2的每个节点到llist1?这不会打败链表的效率????

3 个答案:

答案 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)。

缺点:

  • 不支持Count。
  • Concat操作使第二个列表处于不一致状态。
  • 拆分操作会使原始列表处于不一致状态。
  • 您可以在列表之间共享节点。

其他:

  • 我选择了一种替代策略来实现枚举和查找操作,而不是更详细和纯粹可读的原始实现。我希望负面的业绩影响仍然微不足道。