【问题标题】:How to make improve performance on my implement of this LinkedList? [closed]如何提高我实现此 LinkedList 的性能? [关闭]
【发布时间】:2018-01-20 11:09:03
【问题描述】:

问题如下

TrainComposition 是通过从 左侧和右侧,在使用时间方面有效。

例如,如果我们首先从左侧连接 7 号货车,然后 通过附加货车 13,再次从左侧,我们得到一个组合 两辆货车(从左到右分别为 13 和 7)。现在第一辆可以 右边是7和第一个可以分离的 从左到右是 13。

实现一个对这个问题建模的 TrainComposition。

这个问题可能仍然与如何解决项目列表的排序有关。最初,我针对 Testdome 练习中提出的此类问题提交了一个答案。虽然答案在逻辑上是正确的,但它缺乏性能要求。因此,我在这里提出了这个问题。

我更新的问题,如下:

我已经查看了不同的集合类型,但我一直在思考如何通过我的这个 LinkedList 的实现来提高性能。

我需要的行为是 LinkedList 集合的行为,但性能很弱。您是否看到我可以进行任何调整以提高性能?也许还有另一种类型的集合,可以提供链表的功能并提高性能。我还在解决这个问题。感谢您的帮助。

using System;
using System.Collections.Generic;
using System.Linq;

public class TrainComposition
{

    public TrainComposition()
    {
        Wagons = new LinkedList<int>();
    }

    private LinkedList<int> Wagons;

    public void AttachWagonFromLeft(int wagonId)
    {
        Wagons.AddFirst(wagonId);
    }

    public void AttachWagonFromRight(int wagonId)
    {
        Wagons.AddLast(wagonId);
    }

    public int DetachWagonFromLeft()
    {
        var wagon = Wagons.First.Value;
        Wagons.Remove(wagon);
        return wagon;
    }

    public int DetachWagonFromRight()
    {
        var wagon = Wagons.Last.Value;
        Wagons.Remove(wagon);
        return wagon;
    }

    public static void Main(string[] args)
    {
        TrainComposition tree = new TrainComposition();
        tree.AttachWagonFromLeft(7);
        tree.AttachWagonFromLeft(13);
        Console.WriteLine(tree.DetachWagonFromRight()); // 7 
        Console.WriteLine(tree.DetachWagonFromLeft()); // 13
    }
}

here 提出了类似的问题,但使用的是 java 而不是 C#。因此,库不同,我认为这是一个未提出的问题。

编辑

为清楚起见,请参考上述Testdome问题描述。

如果可能的话,把我上面的代码,插入到Testdome客户端代码编辑框中运行测试并查看结果,如下:

  • 示例案例:正确答案
  • 几辆货车:正确答案
  • 性能测试大量货车:超过时间限制

编辑

使用列表,如下,我也无法通过性能要求:

    public TrainComposition()
    {
        Wagons = new List<int>();
    }

    private List<int> Wagons;

    public void AttachWagonFromLeft(int wagonId) // insert at index 0
    {
        Wagons.Insert(0, wagonId);
    }

    public void AttachWagonFromRight(int wagonId) // add item to last/end 
    {
        Wagons.Add(wagonId);
    }

    public int DetachWagonFromLeft() // remove first item (index = 0)
    {
        var wagon = Wagons[0];
        Wagons.RemoveAt(0);
        return wagon;
    }

    public int DetachWagonFromRight() // remove last item (index = count - 1)
    {
        var lastWagonIndex = Wagons.Count() - 1;
        var wagon = Wagons[lastWagonIndex];
        Wagons.RemoveAt(lastWagonIndex);
        return wagon;
    }

最新更新

敬请期待,我正在努力更新此问题以提供 codepen...

【问题讨论】:

  • 您的 DetachWagonFromRight 方法实际上并没有删除最后一个元素 - 如果您在 LinkedList 中有另一个元素具有相同的值,则会被删除
  • 您在寻找什么样的性能改进?你如何衡量?
  • 您可能需要考虑List&lt;T&gt; 而不是LinkedList
  • 我不知道您的性能问题是什么(您还没有定义它们),我不知道您的性能目标是什么(您还没有定义它们)。即使我仍然使用List,小提琴here 制作了您的代码的快速版本

标签: c# performance collections


【解决方案1】:

最后,起作用的是Steven Cleary's C# implement of Deque,以及以下内容:

public TrainComposition()
{
    Wagons = new Deque<int>();
}

private Deque<int> Wagons;

public void AttachWagonFromLeft(int wagonId)
{
    Wagons.AddToBack(wagonId);
}

public void AttachWagonFromRight(int wagonId)
{
    Wagons.AddToFront(wagonId);
}

public int DetachWagonFromLeft()
{
    return Wagons.RemoveFromBack();
}

public int DetachWagonFromRight()
{
    return Wagons.RemoveFromFront();
}

有没有比实现整个 Cleary 的 C# Deque 更简单的解决方案?

正如 Ivan 在下面评论的那样,使用LinkedList 和调用RemoveFirst()RemoveLast() 可以实现相同的目标,如下所示:

public TrainComposition()
{
    Wagons = new LinkedList<int>();
}

private LinkedList<int> Wagons;

public void AttachWagonFromLeft(int wagonId)
{
    Wagons.AddFirst(wagonId);
}

public void AttachWagonFromRight(int wagonId)
{
    Wagons.AddLast(wagonId);
}

public int DetachWagonFromLeft()
{
    var wagon = Wagons.First.Value;
    Wagons.RemoveFirst();
    return wagon;
}

public int DetachWagonFromRight()
{
    var wagon = Wagons.Last.Value;
    Wagons.RemoveLast();
    return wagon;
}

【讨论】:

  • 那个解决方案对你来说不够简单怎么办?每种方法都只有一行 - 我不确定如何可能让它变得更简单。
  • mjwills:我指的是 Deque。看看 Cleary 的 Deque 实现(我的答案中的链接)。我还没有时间仔细看。我会的,因为我有兴趣了解它如何在 LinkedList 集合上实现性能。如果我需要具有改进性能的 LinkedList 功能,那么 Cleary 的 Deque 是我现在的 C# 选择。谢谢!
  • LinkedList 确实是这项任务的最佳选择。唯一低效的部分是Detach 方法中的Remove 调用,因为它们涉及不必要的线性搜索。分别用RemofeFirst()RemoveLast() 替换它们,你就完成了。
  • @Ivan Stoev - 你是对的。我回去查看了我的答案。我已经编辑了我的答案以包含 LinkedList 的代码以及您调用 RemoveFirst() 和 RemoveLast() 的建议。谢谢!!
  • @AdamCox:FWIW,您原始代码中的根本错误是您使用列表中的 value 调用 remove,而不是使用 a node。要很好地使用LinkedList,请始终使用nodes。最后没关系,因为RemoveFirstRemoveLast 存在。但在更一般的算法中,传递 nodes,而不是 valuesWagons.FirstWagons.Last 是节点。如果RemoveFirst 不存在,则DetachWagonFromLeft() 的基于节点的实现是var node = Wagons.First; Wagons.Remove(node); return node.Value; 这与RemoveFirst 一样高效。
猜你喜欢
  • 2018-02-14
  • 1970-01-01
  • 1970-01-01
  • 2017-01-31
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
  • 2012-06-30
  • 2018-02-24
相关资源
最近更新 更多