ANSI C中的树数据结构

时间:2012-08-13 21:49:07

标签: c data-structures

如何在ANSI C(*)中实现树?

struct Element
{
    ...
    struct Element *pChildElements; // Use dynamic array?
};

(*)我的意思是树的最一般定义(不是二叉树)。

2 个答案:

答案 0 :(得分:3)

最佳实施方法(也有很多)可能取决于具体的应用。例如,在某些应用程序中,将子节点或子指针存储在数组中可能更为可取,而在其他应用程序中则完全没有必要。你真的需要基于索引的随机访问孩子吗?如果是这样,请使用数组。

实现任意树的经典非数组方法是在每个节点中存储两个指针:指向拳头子节点的指针和指向 next 兄弟节点的指针

struct Element
{
  ...
  struct Element *p_first_child;
  struct Element *p_next_sibling;
};

即。每个节点基本上都包含一个指向其子节点的列表的指针。

例如,具有3个子节点的节点由以下链接结构

表示
    Node
     |
  (first child)
     |
     V
   Child1 --(next sibling)--> Child2 --(next sibling)--> Child3

此实现可以通过在每个节点中仅使用两个指针来存储任何树。无需额外的阵列。由于子节点存储在列表中,因此只能以顺序方式访问它们。

从这种方法得出的有趣观察结果是,结果数据结构可以被认为是二进制树,即任意树可以用等价物表示二叉树。

答案 1 :(得分:0)

您在实现元素结构方面做得很好,但尝试使用二叉树或B树来避免动态分配/解除分配。

此外,您还将提供一组函数来插入/删除/初始化/搜索/排序/枚举树。

你可以想出一个像AddToMyBTree这样的名字(指向树头的指针,新元素)

如果您愿意,可以提供比常规操作更多的功能。

我想我误解了你的问题: 如果你想枚举树元素肯定会使用递归,你也需要使用null对象终止子元素列表,或者添加带子元素数的额外元素。

ProcessNode(element* pElement)
{
    element* pChild = pElement.pChildElements;

    // process the element here


    // then begin to process the child elements.
    while (pChild)
    {
        ProcessNode(pChild);
        pChild++;
    }
}

请记住,您可以将指针传递给处理元素的函数,以便此枚举器可以是您的树的通用。