我正在阅读作者Robert Sedwick在C ++中的Algorithms中使用符号表的索引实现。
以下是本书的摘录
我们可以调整二元搜索树来精确构建索引 与我们提供间接排序和堆的方式相同。 安排通过密钥成员从项目中提取密钥 功能,像往常一样。而且,我们可以使用并行数组 链接,就像我们为链接列表所做的那样。我们使用三个数组,每个数组一个 项目,左链接和右链接。链接是数组索引 (整数),我们替换链接引用,如
x = x-> l
在所有代码中都有数组引用,如
x = l [x]。
这种方法避免了每种方法的动态内存分配成本 节点 - 项目占用数组而不考虑搜索功能, 我们为每个项目预分配两个整数来保存树链接, 认识到我们至少需要这么多的空间 这些项目在搜索结构中。链接的空间不是 总是在使用,但它没有用于搜索程序 分配的任何时间开销。这个的另一个重要特征 方法是它允许额外的数组(相关的额外信息 在没有树操作代码的情况下添加每个节点) 完全改变了。当搜索例程返回项目的索引时, 它提供了一种立即访问所有相关信息的方法 使用该项,通过使用索引访问适当的数组。
这种实现BST的方式有助于搜索大型数组 物品有时是有用的,因为它避免了额外的费用 将项目复制到ADT的内部表示中,以及 新的分配和建设的开销。数组的使用是 当空间非常宝贵并且符号表增长时,这是不合适的 并且显着缩小,特别是如果难以估计的话 提前符号表的最大大小。如果没有准确的尺寸 预测是可能的,未使用的链接可能会浪费项目中的空间 阵列。
我对上述文字的疑问是
作者的意思是“我们可以像链接列表一样使用并行数组作为链接”吗?这个定义是什么意思,什么是并行数组。
作者的意思是链接是数组索引,我们用x = l [x]替换x = x-> l的链接引用?
作者的意思是“这种方法的另一个重要特征是它允许添加额外的数组(与每个节点相关的额外信息),而根本不更改树操作代码。”
答案 0 :(得分:1)
您似乎已编辑了文本以取出有用的参考资料。要么你或你有一个早期版本的文本。
我的第三版说明索引构建在第9.6节中介绍,其中介绍了该过程,并且并行数组在第3章中进行了解释。并行数组只是存储有效负载(密钥和可能持有的数据)在树中)和三个或更多单独数组中的左/右指针,使用索引将它们绑定在一起(x = left[x]
)。在这种情况下,您可能会得到类似的结果:
int leftptr[100];
int rightptr[100];
char *payload[100];
等等。在该示例中,节点#74将其数据存储在payload[74]
中,左右“指针”(实际上是索引)分别存储在left[74]
和right[74]
中。
这与具有结构的单个数组结构形成对比,结构将有效负载和指针保持在一起(x = x->left;
):
struct sNode {
struct sNode *left, right;
char payload[];
};
因此,针对您的具体问题:
并行数组只是将树结构信息与有效负载信息分开,并使用索引将这些数组中的信息绑定在一起。
由于您正在为链接使用数组(并且这些数组现在包含数组索引而不是指针),因此您不再使用x = x->left
移动到左子节点。相反,您使用x = left[x]
。
树操作只对链接感兴趣。通过将链接与有效负载(以及其他可能有用的信息)分开,操作树结构的代码可以更简单。
答案 1 :(得分:0)
如果你还没有,你应该在书中回到关于链接列表的部分,他说这个技术以前用过(可能在那里解释过)。
并行数组意味着我们没有结构来保存节点信息。
struct node {
int data;
struct node *left;
struct node *right;
};
相反,我们有阵列。
int data[SIZE];
int left[SIZE];
int right[SIZE];
这些是并行数组,因为我们将使用相同的索引来访问数据和链接。节点在我们的代码中由索引表示,而不是指针。因此,对于节点4,数据位于
data[4];
左侧链接位于
left[4];
在节点上添加更多信息可以通过创建另一个相同大小的数组来完成。
int extra[SIZE];
节点4的额外数据将在
extra[4];