【问题标题】:Does this array-based data structure have a name?这个基于数组的数据结构有名字吗?
【发布时间】:2016-08-27 13:36:48
【问题描述】:

我一直在使用特定的数据结构做很多工作,我主要将其用作平面树结构中项目的索引。它由一个正整数数组(或字节、长整数或其他)组成,每个数组都被认为处于与其在数组中的索引相等的“深度”。

将其视为树中的索引,树的根有一个空数组作为其索引,索引为{a, b... c} 的给定节点的第 N 个子节点的索引为{a, b... c, N}。

对它的常见操作递增/递减数组中的最后一个数字,从前面或后面删除一些元素,并将一些元素附加到前面或后面。在树索引上下文中,这些对应于通过兄弟节点向前/向后步进,在子树中查找索引或查找父节点的索引,当树的根被卡在另一棵树上时查找索引并查找某些索引后代节点。

虽然我最初只是将它们用作索引,但我不断发现将它们用于从加速数据序列化到使代码更具可读性等目的的新方法。这让我想知道,这种数据结构或类似的东西是否在其他地方普遍使用?如果有,它有名字吗?我很想看看我还能用这个做什么。

(C# 中的示例实现,省略了错误检查以保持可读性)

class TreeIndex
{
    public readonly int depth
    {
        get
        {
            return widths.Length;
        }
    }
    public readonly int[] widths;

    public TreeIndex()
    {
        widths = new int[0];
    }
    public TreeIndex(params int[] indices)
    {
        widths = indices;
    }
    public static implicit operator int(TagIndex ti)
    {
        return ti[ti.depth - 1];
    }
    public static operator TagIndex +(TagIndex ti, int i)
    {
        int[] newwidths = ti.widths.Clone();
        newwidths[newwidths.Length - 1] += i;
        return new TagIndex(newwidths);
    }
    public static operator TagIndex -(TagIndex ti, int i) { return ti + (-i); }
    public static operator TagIndex <<(TagIndex ti, int i)
    {
        int[] newwidths = new int[ti.depth - i];
        Array.Copy(ti.widths, newwidths, ti.depth - i);
        return new TagIndex(newwidths);
    }
    public static operator TagIndex >>(TagIndex ti, int i)
    {
        int newwidths = new int[ti.depth - i];
        Array.Copy(ti.widths, i, newwidths, 0, ti.depth - i);
        return new TagIndex(newwidths);
    }
    public static operator TagIndex ^(TagIndex tia, TagIndex tib) 
    {
        int newwidths = new int[tia.depth + tib.depth];
        Array.Copy(tia.widths, newwidths, tia.depth);
        Array.Copy(tib.widths, 0, newwidths, tia.depth, tib.depth);
        return new TagIndex(newwidths);
    }
}

【问题讨论】:

  • 尽管有重载的运算符和具体的用例,但作为一个数据结构,这实际上只是一个列表。
  • 是这样吗?我不太清楚什么构成了我认为的独特数据结构。我见过许多类似的问题,似乎是根据操作而非内容来定义它们,这是不正确的吗?

标签: arrays data-structures terminology


【解决方案1】:

评论是正确的:它只是一个列表。

考虑List&lt;T&gt; 类。您可以通过设置Capacity 属性来增加或减少其容量(类似于- 和+ 运算符)。您可以通过调用AddRange 将项目添加到列表的末尾。您可以通过调用InsertRange 在列表中的任何位置插入项目。删除项目只需致电RemoveRange。

您的^ 运算符很简单:

list1.AddRange(list2);

List&lt;T&gt; 完成了您的数据结构所做的一切,除此之外,还包括实现所有常见的集合接口:IList、ICollection、IEnumerable 等。它是每个 .NET 程序员都可以使用的通用数据结构熟悉。如果您曾设想其他人在处理您的代码,那么建议您使用List&lt;T&gt;,而不是使用其他人不熟悉的非标准语义和疯狂的重载来滚动您自己的自定义类。

【讨论】:

  • 仅供参考,我对这个结构所做的大部分工作都不是在 C# 中。我为我的示例选择了 C# 实现,因为在 C# 中删除错误检查所需的工作比从 C 实现中删除内存管理所需的工作少得多。就列表/接口而言,虽然我知道在代码可能被许多人使用、管理和扩展的情况下,熟悉和清晰的好处远远超过了我为自己编写代码时所产生的轻微性能损失, 性能密集型使用我倾向于定制解决方案。
  • @P...:明白。 C# 并不是唯一具有这种数据结构的语言。 Java 的ArrayList 具有类似的功能,Python、Javascript 以及我认为的 PHP 也是如此。可能每一种现代语言都有一个类比。
  • 更多地查看通常称为“数据结构”的事物的示例,我必须要求更多地澄清某些事物必须具有多大的独特性才能获得资格。通过与上面使用的参数类似的参数,您可以说整数列表、整数数组和单个整数都是相同的数据结构,只是随着您的进步,功能越来越少。
  • @P...:我不同意。原始类型和该类型的数组之间存在根本区别。这种类型的动态数组增加了另一个级别的功能,我认为这使它成为一种不同的数据类型。但是您说得对,至少最后两个是我们称为集合的抽象数据类型的示例。或者一个清单。您的索引只是普通动态数组或列表的特化。我并不是说它的好坏,而是说它是大多数现代编程语言中常见的功能的一个子集。
  • @JimMischel 不幸的是,他说“C 实现”,在 C 中,如果你想要一个列表,你必须自己制作。我很想看看 C 实现是如何使用的,因为 C 没有运算符重载......
猜你喜欢
  • 1970-01-01
  • 2013-06-03
  • 2013-04-11
  • 2011-05-08
  • 2011-01-30
  • 2023-03-21
  • 1970-01-01
  • 2015-01-05
  • 1970-01-01
相关资源
最近更新 更多