【问题标题】:Best way to index a tree索引树的最佳方法
【发布时间】:2015-02-24 04:10:34
【问题描述】:

我有一棵树,其节点数从 100 到超过 500,000 不等。树中的每个节点都有一个唯一的 id。由于树中有大量节点,解析到树以在其中搜索节点的计算量很大。所以我想实现一个索引数据结构,它有 id 和另一个指向节点的指针,什么是实现这个索引数据结构的最佳方法,我想用数组来做,但它赢了'没有帮助,因为在执行之前节点的数量是未知的。

树中的节点数可能超过 500K 并且动态增加,树中的节点根据唯一 id 不相关,此 id 用于与其他节点区分,主要用于搜索节点在树上。

下面的例子可能会给出关于树的粗略概念(但这不是实际场景,只是用它来解释树)。

假设树描述的是车辆,根节点下的每个节点 对车辆类型进行分类,比如说两轮车、火车、四 轮车、卡车等在此节点下可能还有更多 基于其他标准(如品牌、型号、发动机等)的分类。 并且每个节点都将具有很少的属性(例如在 xml 中)。所以最后我们 如果节点存在,将使用 id 搜索节点是否存在 属性,树上还有多个其他功能, 搜索就是其中之一,它会消耗大量时间。

【问题讨论】:

  • 你能定义ID的性质吗?
  • id 为整数,仅用于区分一个节点与另一个节点,添加新节点时递增。
  • IMO 可以使用链式哈希。在链式哈希情况下,您可以选择 KEY 作为 ID 范围的公共键 [Ex- ID 0 到 1000 在一个链式链表中]..
  • btw 节点是动态创建的吗?我的意思是,在将它们添加到所需的数据结构之前,您知道有多少个节点吗?
  • @KcDoD 问题是不同节点的标准不同,我会尝试概括它,但我不确定我是否能很好地解释它,例如,让我们假设树是车辆,父节点下方的每个节点都不能确定车辆类型(如两轮车、四轮车、火车等),并且对于每个节点,可能还有其他节点确定车轮或发动机的类型或其他特性。 这不是实际场景,我只是试图用这个来解释

标签: c data-structures


【解决方案1】:

由于无法估计树节点的数量,您可以使用另一种平衡搜索树,例如 R-B 树,将地址存储到您的树节点。

例如,这样定义平衡搜索树的节点结构:

struct rb_node
{
    int id;
    node *n; //pointer to your tree node
};

然后根据id构建平衡搜索树。

每次向树中插入一个节点时,也要向平衡树中插入一个节点。然后你可以使用id快速找到节点。

【讨论】:

  • 既然每次插入节点都需要做平衡,那会不会是个开销呢?我以前想过这个,但我发现,这对我们有帮助,当你构建一棵树时,平衡它并搜索它(搜索完成多次,但树只构建一次),但我需要搜索节点在构建树时,不时平衡它会导致开销。如果我错了,请纠正我。
  • 既然知道id和另一个指向节点的指针,唯一的开销就是构建一个平衡的搜索树,可以忽略。
  • 我们不需要对树进行多次平衡吗?你将如何确定何时平衡它?平衡的时间复杂度是多少?我怀疑平衡搜索树的开销是否可以忽略。
  • 平衡是平衡搜索树插入/删除的一部分,只需要常数时间,即O(1)。相比O(log n),插入/删除的时间复杂度,可以直接忽略。
  • @Naks 平衡的有效开销取决于节点添加和删除相对于节点搜索的频率。如果你构建整个树,那么主要是搜索它,一步构建索引树而不是增量。如果您多次搜索一个或几个节点,请使用自适应索引树,例如加权树或展开树。
【解决方案2】:

您所说的有一个 id 字段,然后是一个与之关联的 node 指针字段,这听起来像是 hashmap(或 hashtable,或者你有什么)。

如果您不知道这是什么,那么您基本上有一个只能变大(2 的幂)的数组,其中填充了节点。当您想要添加数据时,您对键执行 散列 计算,在这种情况下,它是 id 字段。这给了你一些数字。然后你说number % size_of_array。这需要模余数来获得实际上在数组大小范围内的数组元素。假设您的数组大小是 2 的幂次方,您可以确保所有节点都被填充。

您还需要许多其他功能,您可以在某处了解它们。

现在,(或假设您已经了解哈希图)您将 id 字段用作每个节点的 key,并且每个节点的 value 指针将是指向树节点的指针。这通常相当快,除非您有很多冲突,或具有相同哈希的节点,尽管通常您不必重新哈希超过两到三次。

struct hashnode {
  void *key;  //This is the id field.
  void *value;  //This points to the tree node.
}

struct hashmap {
  uint32_t size;
  uint32_t used;

  hashnode *nodes;
};

【讨论】:

  • 感谢您的解释,这与 KcDoD 建议的链式哈希相同。截至目前,我认为这是我最后的手段
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 2013-07-10
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
  • 2020-03-24
相关资源
最近更新 更多