【问题标题】:Does c#/.net x.x have an implementation of a doubly linked list (that can be iterated over backwards)?c#/.net x.x 是否有双向链表的实现(可以向后迭代)?
【发布时间】:2010-01-26 00:27:18
【问题描述】:

我一直在寻找 C# 中双向链表的标准实现(这样我就有了一个可以向后迭代的链表),但找不到。我觉得这么简单的东西必须有一个我只是缺少的实现。

如果存在,它存在于哪个版本的c#/.net?

一般来说,反向迭代似乎是不打算在 c# 中完成的事情。是我的思绪在 c++/stl 模式中停留的太多,还是 c# 中严重缺乏的东西?

我知道 LinkedList,但未能找到向后迭代它的方法,因此假设它是单链接的。

如果 LinkedList 是双向链接的,如何进行反向迭代(高效)?

【问题讨论】:

    标签: c# .net collections linked-list iteration


    【解决方案1】:

    以下代码将有效地反向迭代 LinkedList:

            LinkedList<string> list = new LinkedList<string>
                (new[] {"cat", "dog", "frog", "antelope", "gazelle"});
            LinkedListNode<string> item = list.Last;
            do
            {
                Console.WriteLine(item.Value);
                item = item.Previous;
            }
            while (item != null);
            Console.ReadKey();
    

    这里的关键是 LinkedList 仅包含对列表的 First 和 Last LinkedListNode 实例的引用。每个 LinkedListNode 实例都包含对列表中下一项和上一项的引用(或在列表的每一端为 null)以及一个 Value 属性。这意味着从第一个或最后一个 LinkedListNode 迭代很容易,但随机访问需要从列表中的第一个或最后一个迭代。

    如果需要一路插入,可以使用 LinkedList.AddBefore 或 AddAfter 插入新的 LinkedListNode。

    【讨论】:

    • 这就是我一直在寻找的。出于某种原因,我的印象是 List.Last 会返回 T 类型的东西。谢谢。不知何故,您似乎是唯一一个完全理解问题甚至链表背后概念的人:/
    • 一个被严重低估的容器。很高兴能提供帮助。
    • 如果列表为空,这将引发 ArgumentNullException。将 do/while 循环更改为(更易于阅读,IMO)while 循环将解决问题 - 请参阅我的答案作为示例。
    • 是的,我看到了,只是在脑海中转换为 while 循环,而没有考虑 do/while 的含义。
    【解决方案2】:

    除了这里给出的答案,你还可以为LinkedList&lt;T&gt;写一个扩展方法,让它更容易重用:

    public static IEnumerable<T> Backwards<T>(this LinkedList<T> list)
    {
        LinkedListNode<T> node= list.Last;
        while (node != null)
        {
            yield return node.Value;
            node = node.Previous;
        }
    }
    

    用于:

    foreach (string x in list.Backwards())
    {
        // ...
    }
    

    【讨论】:

    • 谢谢。我有点困惑为什么这样的东西不只是在标准库中。
    • @Catskul 这是一个很好的链接,解释了blogs.msdn.com/ericlippert/archive/2009/05/18/…
    • @Matt:谢谢。恕我直言,在列表上向后迭代是比那里讨论的“ForEach”更基本的功能(例如,大多数 STL 容器都提供向后迭代),尽管它不存在,但似乎 C# 创建者在建议你不应该这样做。在 C# 中,即使我知道如何通过自己实现来做某事,我也觉得如果我没有找到简单的方法,我一定是错过了什么/做错了什么。
    【解决方案3】:

    System.Collections.Generic.LinkedList() 怎么样

    这是 MSDN 上的文档:

    http://msdn.microsoft.com/en-us/library/he2s3bh7.aspx

    版本信息
    .NET Framework:支持:3.5、3.0、2.0
    .NET Compact Framework:受以下版本支持:3.5、2.0
    XNA 框架:支持:3.0、2.0、1.0

    也就是说,我和其他人一样,在使用如此丰富的框架时,通常更喜欢使用更高的抽象。

    【讨论】:

    • 我特别需要能够向后迭代列表,并进行廉价插入 + 廉价重新排序。
    • 好的,那么我回答的第一部分应该对你有所帮助。
    • RTFM 没有帮助,尤其是因为文档没有专门处理反向迭代。如果我们只是要告诉所有人使用 RTFM,那为什么还要使用 Stackoverflow?
    • 这几乎不是 RTFM。您询问了双向链表的 .net 实现,我给了您相关框架对象的名称,回答了您关于哪些版本的框架支持它的问题,并为您提供了相关文档的链接。您从未要求代码显示反向迭代,您只是在思考是否打算这样做。我没有回答的唯一问题是“我的思想只是卡住了......”我认为这是修辞。
    • 对不起,我误解了你。 “好的,那么我的答案的第一部分应该对你有帮助” 对我的迭代推荐的回应似乎是一个 RTFM。
    【解决方案4】:

    LinkedList怎么样?

    【讨论】:

    • 如何有效地向后迭代?
    • while (nodeP != null) nodeP = nodeP.Previous;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-09
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    相关资源
    最近更新 更多