树 - 被连接的非循环图表 - 表示法

时间:2016-12-14 04:42:55

标签: c data-structures graph tree

来自wiki

  

树是一个无向图,其中任意两个顶点只由一个 Path 连接。

路径是连接的边缘序列

树 - 示例:

enter image description here

编写 rooted 树的多步表示相对容易,

typedef struct multiWalkTreeNode{
  struct multiWalkTreeNode * parent;
  void *item;
  struct multiWalkTreeNode **childPointer;
}Node;

typedef struct multiWalkTree{
  Node *root;
  int size; /*Number of nodes in the tree*/
}Tree;

问题:

在树(非根)中,任何节点都没有子/祖先

1)

如何表示树(非root)?

2)从保持巨大的树木&更好的find()性能方面,我们是否有多个表示树(非根)?

2 个答案:

答案 0 :(得分:3)

1)不要单独跟踪childparent个链接,只需将parent指针添加到child并使用child作为完整列表相邻顶点。从实际的角度来看,你必须保持一个指向某个顶点的指针作为find()的入口点,否则就不会有任何关于任何一个节点的特殊情况。

2)两种最常用的树导航方法是深度优先搜索和广度优先搜索。通常,广度检查在对子项进行递归调用之前是否有任何子项是请求的节点。深度检查本身然后对子项执行递归调用,直到它到达叶子。 从记忆的角度来看,这些都不是特别有效,但它们很简单,可以写作。

您可以在任何节点上开始搜索树,搜索时间会有很大差异,但我不会将其称为同一树的不同表示。

答案 1 :(得分:1)

表示树(有向或无向)的两种基本方式是邻接矩阵邻接列表。如果它是一个“密集”树(即 n 2 超过一半的 n 节点的树的可能边),那么它是更有效地将其表示为矩阵。如果它是一个“稀疏”树(少于可能 n 2 边缘的一半),则邻接列表更有效。

您的示例树,表示为邻接矩阵,如下所示:(请原谅ASCII艺术)

     1 2 3 4 5 6
    -------------
 1:  0 0 0 1 0 0
 2:  0 0 0 1 0 0
 3:  0 0 0 1 0 0
 4:  1 1 1 0 1 0
 5:  0 0 0 1 0 1
 6:  0 0 0 0 1 0

每个索引(水平和垂直)对应一个节点,如果该行的节点具有该列节点的边缘,或1,则0放置在矩阵中如果没有边缘。例如,节点3和4之间存在边缘,因此在矩阵中,位置(3,4)具有1。 (不要忘记在C中,当然,数组索引从0开始。我从1开始,因为那是最低节点的标签,这只是一个例子。)

这是一个对称矩阵,因为它是一个无向图。您可以使用行索引作为边的源,并将列作为边的目标,来实现有向图。另一个扩展是通过使用矩阵中的值作为边的权重来制作加权有向图,而不仅仅是1

但请注意这对你的图表来说是多么低效。对于具有 n 节点的图形,您需要 n × n 矩阵(就空间而言, n 2 < / sup> 乘以存储一个值的大小)。无论如何,大多数空格都是空的(0)。

另一个基本方法是邻接列表,它就是:相邻节点列表--- 边缘列表。图表的邻接列表可能是:

   1,4
   2,4
   3,4
   4,5
   5,6

只要你知道这是一个无向图,你只能记录1,4并且只知道它相当于4,1。当然,对于有向图,你可以说1,4表示“从1到4”。请注意,您必须使用邻接列表表示存储的信息量取决于边缘的数量,而不是节点的数量与矩阵表示一样。

我将让你弄清楚如何在C中实现一个二维矩阵或一对值列表。

请注意,邻接矩阵和邻接列表仅表示节点之间的 edge 。您可能还希望在每个节点中存储一些数据。这需要一个单独的结构,例如列表或数组。