来自wiki,
树是一个无向图,其中任意两个顶点只由一个 Path 连接。
路径是连接的边缘序列
编写 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()
性能方面,我们是否有多个表示树(非根)?
答案 0 :(得分:3)
1)不要单独跟踪child
和parent
个链接,只需将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 。您可能还希望在每个节点中存储一些数据。这需要一个单独的结构,例如列表或数组。