繁体   English   中英

什么数据结构适合我的情况?

[英]What data structure(s) are appropriate for my situation?

首先,这可能是一个XY问题,对此感到抱歉。

我正在从文件加载文件表,并将其放入内存文件树中。 树中的节点表示树中的目录/文件。 当前,我在每个节点上使用两个数据结构,由于要插入集合中,因此会导致明显的加载时间,并且由于复制字符串数据并两次引用每个节点而导致较高的内存使用率。 树只加载一次,此后不会变异。

每个节点都有一个用于访问排序后的子节点的列表和一个用于按名称访问子节点的字典。 出于性能原因,该列表被延迟排序。 SortedDictionary不符合我的使用要求,因为我需要将有子节点的节点排序在没有子节点的节点之上,因此传递IComparer是不够的。 当两个节点都具有/不具有子节点时,则将它们按字典顺序排序(OrdinalIgnoreCase)。

.net中是否有满足我需求的数据结构?

另外 ,有什么方法可以在插入字典时为键提供哈希值,并在以后从字典中获取存储桶的一部分(即:GetValuesByHash(int hashValue)会产生其对应键具有给定哈希值的所有值) ? 我正在读取的文件表已经包含整个文件路径的哈希值(适用于我正在做的另一件事),当前,字典无缘无故地只是在重新计算它们。

我认为我可以通过定义自己的自定义键(包括{Hash,Node}和自定义比较器)来破解一个解决方案,但这看起来确实很丑陋,而且您将无法获得共享相同哈希值的节点桶。 如果有的话,那仍然会感觉使用了错误的数据结构。

我已经用Google搜索“ c#dictionary get hash”以及其他一些查询,尽管在这一点上,我还没有看到任何类似的问题。

总体而言,寻找具有以下属性的数据结构(可能与字典相关):

  • ContainsKeyOfHash(),Get(哈希):文件名哈希->文件条目描述符
  • ContainsKey(),Get(key):文件名->文件条目描述符
  • Add(字符串fileName,Entry条目,int hash = gethash(fileName))
  • 条目排序如下:

      m_children.Sort( (a, b) => { bool aHasChildren = a.HasChildren; bool bHasChildren = b.HasChildren; if (aHasChildren && !bHasChildren) return 1; if (!aHasChildren && bHasChildren) return -1; else return -String.Compare(a.m_resourceName, b.m_resourceName, StringComparison.OrdinalIgnoreCase); } ); 
  • 可以按照以上排序的顺序检索所有子节点。 目前,我有一个ChildrenSorted和ChildrenUnsorted属性。 ChildrenSorted属性可能会因排序而对性能造成影响,而ChildrenUnsorted属性则不会。

我认为更糟糕的是,我的解决方案是编写自己的类似于字典的类。 我不必从字典中删除键,因此它并不难。 不过,我有点想避免这样做。

可以在以下位置查看我的节点实现: http : //pastie.org/5547925

谢谢!

我认为您的解决方案已经不错。 这里有一些想法:

  1. 对于既可以排序又可以通过键快速访问的集合,我只能想到树形数据结构。 您可能不想要一种为每个项目分配一个对象的数据结构。 堆最好将所有项目都放在一个数组中,从而为您提供最好的服务。 我认为您可以通过以下方式非常有效地构建该结构:首先对所有子项进行排序,然后填充它们(就像您现在正在做的那样)。
  2. 您可能考虑将所有数据填充到单个此类树中。 这将为您节省最多的每个节点的开销(例如本身具有子对象的集合)。 密钥将是以某种有效格式存储的节点“路径”。 它可以是类似于"d1\\d2\\filename"的路径,也可以是string[]

要点(2)是RDBMS的处理方式。

您只需将Sort() lambda放入`IComparer'中即可使用SortedDictionary

public class MyComparer : IComparer, IComparer<MyNode>
{
    public int Compare(object x, object y)
    {
        return Compare(x as MyNode, y as MyNode);
    }

    public int Compare(MyNode x, MyNode y)
    {
        if (ReferenceEquals(x, y))
        {
            return 0;
        }

        if (ReferenceEquals(x, null))
        {
            return -1;
        }

        if (ReferenceEquals(y, null))
        {
            return 1;
        }

        bool xHasChildren = x.HasChildren;
        bool yHasChildren = y.HasChildren;
        if (xHasChildren && !yHasChildren)
            return 1;
        if (!xHasChildren && yHasChildren)
            return -1;
        else
            return String.Compare(y.m_resourceName, x.m_resourceName, StringComparison.OrdinalIgnoreCase);
    }
}

暂无
暂无

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

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