C# 循环引用列表的问题

C# 循环引用列表的问题,c#,list,circular-reference,C#,List,Circular Reference,我有一个小问题,我想听听你的意见 我处理的文件比其他文件都多。从任何文档开始,我需要获取此文档引用的所有文档的id。问题是循环引用是允许的,所以如果A ref B ref C,C也可以ref A,我进入循环。 我如何用C#解决这个问题 一个小例子: 假设这是一个表示文档的类: public class Document { public Document(int id) { this.ID = id; } private int m_ID;

我有一个小问题,我想听听你的意见

我处理的文件比其他文件都多。从任何文档开始,我需要获取此文档引用的所有文档的id。问题是循环引用是允许的,所以如果A ref B ref C,C也可以ref A,我进入循环。 我如何用C#解决这个问题

一个小例子:

假设这是一个表示文档的类:

public class Document
{
    public Document(int id)
    {
        this.ID = id;
    }

    private int m_ID;

    public int ID
    {
        get { return m_ID; }
        set { m_ID = value; }
    }

    private List<Document> m_Children = new List<Document>();

    public List<Document> Children
    {
        get { return m_Children; }
        set { m_Children = value; }
    }

    private List<Document> m_Parent = new List<Document>();

    public List<Document> Parent
    {
        get { return m_Parent; }
        set { m_Parent = value; }
    }

    public Document AddChild(Document child)
    {
        child.Parent.Add(this);
        this.Children.Add(child);

        return child;
    }

    public Document AddChild(int child)
    {
        Document d = new Document(child);

        return AddChild(d);
    }
}
公共类文档
{
公共文件(int id)
{
this.ID=ID;
}
私人国际货币单位ID;
公共整数ID
{
获取{return m_ID;}
设置{m_ID=value;}
}
私有列表m_Children=新列表();
公开儿童名单
{
获取{return m_Children;}
设置{m_Children=value;}
}
私有列表m_Parent=新列表();
公开列表父项
{
获取{return m_Parent;}
设置{m_Parent=value;}
}
公共文档AddChild(文档子级)
{
child.Parent.Add(此);
this.Children.Add(child);
返回儿童;
}
公共文档AddChild(int child)
{
文件d=新文件(子文件);
返回AddChild(d);
}
}
现在,让我们创建一个包含一些引用的文档类:

public static Document CreateReferences()
{
    Document d = new Document(1);

    Document temp = d.AddChild(2);

    for (int i = 3; i < 6; i++)
    {
        temp = temp.AddChild(i);
    }

    temp.AddChild(d);

    return d;
}
公共静态文档CreateReferences()
{
文件d=新文件(1);
文件温度=d.AddChild(2);
对于(int i=3;i<6;i++)
{
临时=临时添加子项(i);
}
临时儿童(d);
返回d;
}
现在我需要在文档类中实现一个方法,如

public List<int> GetReferencedDocuments()
{    }
public List GetReferencedDocuments()
{    }
最好的方法是什么?可以实现任何特定的算法吗

任何建议都是可以接受的


谢谢,最好的方法是做a或a,最好的方法是做a或a,任何树遍历算法都可以


除了要建立的文档列表外,还要维护一个尚未检查的文档队列,将第一个文档添加到该列表中

然后,当队列不为空时,获取下一个文档(如果它不在列表中),然后添加它,并将所有引用的文档添加到队列中



List FoundDocs=newlist任何树遍历算法都可以


除了要建立的文档列表外,还要维护一个尚未检查的文档队列,将第一个文档添加到该列表中

然后,当队列不为空时,获取下一个文档(如果它不在列表中),然后添加它,并将所有引用的文档添加到队列中



List FoundDocs=new List解决递归数据的这种递归搜索有两种主要方法:标记或记录

标记:每次列出文档时,将其标记为已查看。不要处理标记的文档

因此,您的GetReferenceDocuments看起来有点像这样:

GetReferencedDocuments(startpoint)

if(startpoint.flagged)返回null

startpoint.flag

新列表结果=起始点

foreach(中的子文档)

文件(儿童)

结果.追加(getreferenceddocuments(子文档))// 如果不为空

记录:一种类似的方法,但是标记指示器被已经引用的文档列表(可能是单独的ID列表)替换,标记检查是在此列表上搜索此文档


这两种方法都可以,具体取决于对象、大小和比例。如果无法更改文档对象,则必须列出它们。如果扫描中可能有1M个文档,则不希望列出它们。

有两种主要方法可以解决递归数据的这种递归搜索:标记或记录

标记:每次列出文档时,将其标记为已查看。不要处理标记的文档

因此,您的GetReferenceDocuments看起来有点像这样:

GetReferencedDocuments(startpoint)

if(startpoint.flagged)返回null

startpoint.flag

新列表结果=起始点

foreach(中的子文档)

文件(儿童)

结果.追加(getreferenceddocuments(子文档))// 如果不为空

记录:一种类似的方法,但是标记指示器被已经引用的文档列表(可能是单独的ID列表)替换,标记检查是在此列表上搜索此文档


这两种方法都可以,具体取决于对象、大小和比例。如果无法更改文档对象,则必须列出它们。如果扫描中可能有1M个文档,则不希望列出它们。

示例实现:

public List<int> GetReferencedDocuments()
{    
    var referencedIds = new List<int>();
    var queue = new Queue<Document>(this);
    while (queue.Count > 0)
    {
         var newDocuments = queue.Dequeue().Children
                                           .Where(d => !referencedIds.Contains(d.ID))
         foreach (Document newDocument in newDocuments) 
         {
             queue.Enqueue(newDocument);
             referencedIds.Add(newDocument.ID);
         }
    }
    return referencedIds;
}
public List GetReferencedDocuments()
{    
var referencedIds=新列表();
var queue=新队列(此);
而(queue.Count>0)
{
var newDocuments=queue.Dequeue().Children
.Where(d=>!referencedIds.Contains(d.ID))
foreach(新文档中的文档newDocument)
{
queue.Enqueue(newDocument);
referencedIds.Add(newDocument.ID);
}
}
返回referencedID;
}

实施示例:

public List<int> GetReferencedDocuments()
{    
    var referencedIds = new List<int>();
    var queue = new Queue<Document>(this);
    while (queue.Count > 0)
    {
         var newDocuments = queue.Dequeue().Children
                                           .Where(d => !referencedIds.Contains(d.ID))
         foreach (Document newDocument in newDocuments) 
         {
             queue.Enqueue(newDocument);
             referencedIds.Add(newDocument.ID);
         }
    }
    return referencedIds;
}
public List GetReferencedDocuments()
{    
var referencedIds=新列表();
var queue=新队列(此);
而(queue.Count>0)
{
var newDocuments=queue.Dequeue().Children
.Where(d=>!referencedIds.Contains(d.ID))
foreach(新文档中的文档newDocument)
{
queue.Enqueue(newDocument);
referencedIds.Add(newDocument.ID);
}
}
返回referencedID;
}

是否要获取树的所有父引用或所有引用?顺便说一句(如果你是关于父引用的),循环依赖:你