📜  通用树(N-array Trees)

📅  最后修改于: 2022-05-13 01:57:16.999000             🧑  作者: Mango

通用树(N-array Trees)

通用树是节点的集合,其中每个节点都是一个数据结构,由记录和对其子项的引用列表组成(不允许重复引用)。与链表不同,每个节点存储多个节点的地址。每个节点都存储其子节点的地址,第一个节点的地址将存储在一个名为 root 的单独指针中。

通用树是具有以下属性的 N 叉树:

1. 每个节点都有很多孩子。

2. 每个节点的节点数量事先不知道。

例子:

为了表示上面的树,我们必须考虑最坏的情况,即具有最大子节点的节点(在上面的示例中,6 个子节点)并为每个节点分配那么多指针。
基于这种方法的节点表示可以写为:

C
//Node declaration
struct Node{
   int data;
   struct Node *firstchild;
   struct Node *secondchild;
   struct Node *thirdchild;
   struct Node *fourthchild;
   struct Node *fifthchild;
   struct Node *sixthchild;
}


C
//Node declaration
struct Node{
    int data;
    vector children;
}


C
//Node declaration
struct Node{
    int data;
    struct Node *firstChild;
    struct Node *nextSibling;
}


上述表示的缺点是:

  1. 内存浪费——并非在所有情况下都需要所有指针。因此,存在大量内存浪费。
  2. Unknown number of children – 每个节点的子节点数量事先不知道。

简单的方法:

为了将子节点的地址存储在节点中,我们可以使用数组或链表。但是我们将面临他们两个方面的一些问题。

  1. 链表中,我们不能随机访问任何孩子的地址。所以会很贵。
  2. 数组中,我们可以随机访问任何孩子的地址,但我们只能在其中存储固定数量的孩子地址。

更好的方法:

我们可以使用动态数组来存储孩子的地址。我们可以随机访问任何孩子的地址,并且向量的大小也不是固定的。

C

//Node declaration
struct Node{
    int data;
    vector children;
}

有效的方法:

第一个孩子/下一个兄弟姐妹表示

在第一个孩子/下一个兄弟表示中,采取的步骤是:

在每个节点上,从左到右链接相同父(兄弟)的孩子。

  • 删除从父级到除第一个子级之外的所有子级的链接。

由于我们在孩子之间有一个链接,我们不需要从父母到所有孩子的额外链接。这种表示允许我们从父元素的第一个子元素开始遍历所有元素。

第一个孩子/下一个兄弟表示的节点声明可以写成:

C

//Node declaration
struct Node{
    int data;
    struct Node *firstChild;
    struct Node *nextSibling;
}

优点:

  • 内存效率 - 不需要额外的链接,因此节省了大量内存。
  • 视为二叉树——由于我们能够将任何通用树转换为二叉树表示,我们可以将所有具有第一个子/下一个兄弟表示的通用树视为二叉树。我们只使用 firstChild 和 nextSibling,而不是左右指针。
  • 许多算法可以更容易地表达,因为它只是一棵二叉树。
  • 每个节点都是固定大小的,不需要辅助数组或向量。

父数组中通用树的高度
通用树 - 级别顺序遍历