繁体   English   中英

关于将项目添加到自定义数据类型列表的问题

[英]Question about adding items to a list of a custom datatype

我有一个简单的节点 class。 现在我想将所有相邻的邻居添加到我拥有的列表中的每个节点,但由于某种原因,它只是添加了邻域的第一个相邻节点。 在下面的代码中,“edges”是一个数据树(基本上是一个字典-> int,List),其中每个都由表示一个节点的整数组成。 也许有人可以解释我为什么它只是为每个节点的列表添加一个值,我将非常感激!

节点 class

public class Node
{
  //Properties
  public int name;
  public List<Node> AdjN;
  
  // constructor that takes the current node and initializes the adjList
  public Node(int _node)
  {
    name = _node;
    AdjN = new List<Node>();
  }
}

主要代码:

   var nodes = new List<Node>();   
    for (int i = 0; i < edges.BranchCount; i++) // edges is a datatree which is basically a dictionary (int,List<int>
    {
      Node n1 = new Node(edges.Branch(i)[0]);// this int is the first node of the current edge
      Node n2 = new Node(edges.Branch(i)[1]);/ this int is the second node of the current edge
      
      nodes.Add(n1);
      nodes.Add(n2);
      n1.AdjN.Add(n2); 
      n2.AdjN.Add(n1);     
    }
 
    
    var neighbors = new List<int>();
    for (int i = 0; i < nodes[0].AdjN.Count; i++)
      neighbors.Add(nodes[0].AdjN[i].name);

谢谢大家看这个!

尝试以下操作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, List<int>> edges = new Dictionary<int,List<int>>() {
                { 0, new List<int>(){100,200}},
                { 1, new List<int>(){300,400}},
                { 2, new List<int>(){500,600}},
                { 3, new List<int>(){700,800}}
            };

            var nodes = new List<Node>();   
            for (int i = 0; i < edges.Count; i++) // edges is a datatree which is basically a dictionary (int,List<int>
            {
              Node n1 = new Node(edges[i][0]);// this int is the first node of the current edge
              Node n2 = new Node(edges[i][1]);// this int is the second node of the current edge
      
              nodes.Add(n1);
              nodes.Add(n2);
              n1.AdjN.Add(n2); 
              n2.AdjN.Add(n1);     
            }
 
    
            var neighbors = new List<int>();
            for (int i = 0; i < nodes[0].AdjN.Count; i++)
              neighbors.Add(nodes[0].AdjN[i].name);
  
        }
    }
    public class Node
    {
        //Properties
        public int name;
        public List<Node> AdjN;

        // constructor that takes the current node and initializes the adjList
        public Node(int _node)
        {
            name = _node;
            AdjN = new List<Node>();
        }
    }
}

您当前实现的问题是,如果一个节点连接到多个边,则该节点将多次出现在您的列表中,每次都有一个邻居。 相反,它应该只出现在您的列表中一次,每条边有一个邻居。 这是一个示例图:

B -- A -- C

目前,您按如下方式处理它:

  1. 将节点 B 和 A 添加到列表中,每个节点都将另一个节点列为邻居:
    • B、邻居:A
    • A、邻居:B
  2. 将节点 A(再次)和 C 添加到列表中,每个都将另一个列为邻居。
    • B、邻居:A
    • A、邻居:B
    • A、邻居:C
    • C,邻居:A

节点 A 在您的列表中出现两次,一次将 B 列为邻居,一次将 C 列为。 第二次循环迭代应该注意到 A 已经在列表中,并添加 C 作为另一个邻居。

但是查看A是否已经在你的List中的唯一方法是遍历整个东西,当节点数量很大时效率不高。

尝试将nodes变量从List<Node>数据结构更改为Dictionary<int,Node> ,其中键是节点标识符,值是完整节点。 在循环的每次迭代中,您可以在 O(1) 时间内检查字典中是否存在n1n2 ,并且仅当它们不存在时才将它们添加到字典中。

不要忘记,如果您在Dictionary中找到节点标识符,则需要更新字典中 object 的邻居列表,而不是您创建的 object 的邻居列表,并且恰好具有相同的标识符。

该算法应如下所示:

For each edge
    For j = 0 to 1
        id[j] = node[j] attached to the edge
        if id[j] is in the dictionary
            set n[j] = value from dictionary
        else
            set n[j] = new Node(id[j])
            add n[j] to the dictionary

    add n[1] as neighbor to n[0]
    add n[0] as neighbor to n[1]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM