我一直在使用特定的数据结构做很多工作,我主要用它作为平面树结构中项目的索引。它由一组正整数(或字节,或长或任何)组成,每个都被认为是在“深度”。等于数组中的索引。
将其视为树中的索引,树的根有一个空数组作为索引,而索引为{a, b... c}
的给定节点的第N个子节点具有索引{a, b... c, N}
。 / p>
它上面的常用操作增加/减少数组中的最后一个数字,从前面或后面删除一些元素,并在前面或后面添加一些元素。在树索引上下文中,这些对应于通过兄弟节点向前/向后步进,在子树中查找索引或查找父节点的索引,在树的根粘贴到另一个树并查找时查找索引一些后代节点的索引。
虽然我最初只是将它们用作索引,但我一直在发现将它们用于各种目的的新方法,从加速数据序列化到使代码更具可读性。这让我想知道,这个数据结构还是类似于其他地方常用的东西?如果是这样,它有名字吗?我有兴趣了解我还能做些什么。
(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);
}
}
答案 0 :(得分:0)
评论是正确的:它只是一个列表。
考虑List<T>
课程。您可以通过设置-
属性来增加或减少其容量(类似于+
和Capacity
运算符)。您可以通过调用AddRange
将项目添加到列表末尾。您可以通过调用InsertRange
在列表中的任何位置插入项目。删除项目需要调用RemoveRange
。
您的^
运算符很简单:
list1.AddRange(list2);
List<T>
执行您的数据结构所做的一切,此外还包括实现所有常见的集合接口:IList
,ICollection
,IEnumerable
等。这是一个每个.NET程序员都熟悉的通用数据结构。如果您曾设想其他人正在处理您的代码,那么建议您使用List<T>
而不是使用其他人不熟悉的非标准语义和疯狂重载来推销您自己的自定义类。