【问题标题】:How to properly make a linked list with cursom links?如何正确制作带有自定义链接的链接列表?
【发布时间】:2020-08-09 06:47:54
【问题描述】:

在 C# 中创建 LinkedList 时,可以通过模板LinkedList<T> 指定其节点的类型,但不能指定其链接的类型。它始终是 LinkedListNode。这很奇怪,因为从数学上讲,图节点可以携带数据(边的宽度等)。甚至,这也不是不可能实现的,但他们选择不这样做。我的问题是:如何用自定义节点和链接表示链表?我是否必须编写自己的链表实现?

【问题讨论】:

  • “他们选择不这样做”——这听起来像是一个委员会讨论过的,他们提出了一些建议,然后自愿选择保留该特定功能(出于恶意)。 事实并非如此! 正如 Eric Lippert(他是“他们”的一部分)所说:“功能默认未实现”(例如:stackoverflow.com/a/8673015/1336590) - 现在, LinkedList<T> 可用。这可以作为您自己实施的基础。

标签: c# list types linked-list


【解决方案1】:

是的,您必须自己编写。您可以使用参考源作为入门 https://referencesource.microsoft.com/#System/compmod/system/collections/generic/linkedlist.cs

听起来像一个有趣的项目,如果你在这里发帖问题(带有代码)卡住了

【讨论】:

    【解决方案2】:

    您可以构建自己的链表类型,但也可以只将边缘相关的数据放入存储的对象中。

    一个简单的版本是:

    public class NodeInfo 
    {
      public NodeInfo(string data, double prevWeight = 1.0, double nextWeight = 1.0)
      {
        Data = data;
        PrevLinkWeight = prevWeight;
        NextLinkWeight = nextWeight;
      }
    
      public string Data { get; set; }
      public double PrevLinkWeight { get; set; }
      public double NextLinkWeight { get; set; }
    }
    

    然后您可以像这样添加节点:

    var list = new LinkedList<NodeInfo>();
    list.AddLast(new NodeInfo("Node1", nextWeight: 0.5));
    list.AddLast(new NodeInfo("Node2", prevWeight: 0.5, nextWeight: 1.0));
    list.AddLast(new NodeInfo("Node3", prevWeight: 2.0));
    

    并且,给定LinkedListNode&lt;NodeInfo&gt;,您可以通过这种方式访问​​节点/边缘数据:

    node.Value.Data
    node.Value.NextLinkWeight
    

    更复杂的方法:

    你也可以做一些稍微复杂的事情——例如节点和边有不同的类型:

    // Container class
    public class NodeInfo<TValue>
    {
      public NodeInfo(
        TValue value, 
        LabeledWeightedLink prevLink = null, 
        LabeledWeightedLink nextLink = null)
      {
        Data = value;
        PrevLink = prevLink ?? new LabeledWeightedLink();
        NextLink = nextLink ?? new LabeledWeightedLink();
      }
    
      public TValue Data { get; set; }
      public LabeledWeightedLink PrevLink { get; set; }
      public LabeledWeightedLink NextLink { get; set; }
    }
    
    // Edge-related data
    public class LabeledWeightedLink 
    {
      public LabeledWeightedLink()
        : this(string.Empty, 1.0)
      {}
    
      public LabeledWeightedLink(string label, double weight = 1.0)
      {
        Label = label;
        Weight = weight;
      }
      public string Label {get; set; }
      public double Weight { get; set; }
    
      public override string ToString() => $"lnk(\"{Label}\"; {Weight})";
    }
    

    然后你可以像这样添加节点:

    var list = new LinkedList<NodeInfo<string>>(); 
    
    list.AddLast(new NodeInfo<string>(
      "node1",
      nextLink: new LabeledWeightedLink("1 to 2", 2.0)));
    
    list.AddLast(new NodeInfo<string>(
      "node2", 
      prevLink: new LabeledWeightedLink("2 to 1", 1.0),
      nextLink: new LabeledWeightedLink("2 to 3", 2.0)));
    
    list.AddLast(new NodeInfo<string>(
      "node3",
      prevLink: new LabeledWeightedLink("3 to 2", 2.5),
      nextLink: new LabeledWeightedLink("3 to 4", 1.5)));
    
    list.AddLast(new NodeInfo<string>(
      "node4",
      prevLink: new LabeledWeightedLink("4 to 3", 1.5)));
    

    同样,给定一个节点,您可以通过 NodeInfo 类访问各种感兴趣的属性:

    node.Value.Data
    node.Value.NextLink.Label
    node.Value.NextLink.Weight
    

    例如:

    var current = list.First;
    do {
      string nodeData = current.Value.Data;
      string prevLink = current.Value.PrevLink.ToString();
      string nextLink = current.Value.NextLink.ToString();
      Console.WriteLine($"{prevLink}<---[{nodeData}]--->{nextLink}");
    
      current = current.Next;
    } while (current != null);
    

    打印出来:

    lnk(""; 1)<---[node1]--->lnk("1 to 2"; 2)
    lnk("2 to 1"; 1)<---[node2]--->lnk("2 to 3"; 2)
    lnk("3 to 2"; 2.5)<---[node3]--->lnk("3 to 4"; 1.5)
    lnk("4 to 3"; 1.5)<---[node4]--->lnk(""; 1)
    

    【讨论】:

      猜你喜欢
      • 2022-09-27
      • 2021-11-01
      • 2018-02-11
      • 2012-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      相关资源
      最近更新 更多