jpen
jpen

Reputation: 2147

ANSI C - Appending nodes to arbitrary tree

When appending a new node to an arbitrary tree, would you traverse the tree from the root? Or would you build subtrees and combine them to build a whole tree?

My Node and Tree structures look like:

Node.h

struct _Node;
typedef struct _Node Node;

Node.c

struct _Node
{
    char *pName;
    unsigned char *pValue;
    struct _Node *pFirstChild;
    struct _Node *pNextSibling;
};

Node* NodeCreate(char *pName, uint32_t uLength, unsigned char *pValue)
{
    if (!pValue)
        return NULL;

    Node *pNode = (Node*)malloc(sizeof(Node));
    if (!pNode)
        return NULL;

    pNode->pName = pName;
    pNode->pValue = (unsigned char*)malloc(uLength * sizeof(pValue[0]));
    pNode->pFirstChild = NULL;
    pNode->pNextSibling = NULL;

    return pNode;
}    

Tree.h

struct _Tree;
typedef struct _Tree Tree;

Tree.c

struct _Tree
{
    Node *pRoot;
};

Node* TreeNodeCreate(char *pName, uint32_t uLength, unsigned char *pValue)
{
    return NodeCreate(pName, uLength, pValue);
}

Node* TreeNodeAppend(Node **ppParent, Node *pNode)
{
    if (!((*ppParent)->pFirstChild))
    {
        (*ppParent)->pFirstChild = pNode;

        return (*ppParent)->pFirstChild;
    }

    Node *pLastChild = (*ppParent)->pFirstChild;
    while (pLastChild->pNextSibling)
        pLastChild = pLastChild->pNextSibling;

    pLastChild->pNextSibling = pNode;

    return pLastChild;
}

Node* TreeGetRoot(Tree *pTree)
{
    if (!pTree)
        return NULL;

    return pTree->pRoot;
}

void TreeSetRoot(Tree **ppTree, Node *pNode)
{
    (*ppTree)->pRoot = pNode;
}

main.c

int main()
{
    unsigned char value[] = { 0x01, 0x02, 0x03 };
    uint32_t uLength = sizeof(value) / sizeof(value[0]);

    Tree *pTree = TreeCreate();

    Node *pRoot = TreeNodeCreate("Root", uLength, value);
    TreeSetRoot(&pTree, pRoot); 

    Node *pA = TreeNodeCreate("A", uLength, value);
    Node *pB = TreeNodeCreate("B", uLength, value);
    Node *pC = TreeNodeCreate("C", uLength, value);
    Node *pD = TreeNodeCreate("D", uLength, value);
    Node *pE = TreeNodeCreate("E", uLength, value);
    Node *pF = TreeNodeCreate("F", uLength, value);

    TreeNodeAppend(&pRoot, pA);
    TreeNodeAppend(&pRoot, pB);

    TreeNodeAppend(&pA, pC);
    TreeNodeAppend(&pA, pD);

    TreeNodeAppend(&pB, pE);
    TreeNodeAppend(&pE, pF);

    return 0;
}

Upvotes: 0

Views: 400

Answers (1)

Christian Stieber
Christian Stieber

Reputation: 12496

Well, it depends on how your tree is organized. "Arbitrary tree", and you using an arbitrary number of child nodes is not generally used for something where nodes have a determined order; in most cases, such trees appear when the parent/child relationship is the thing that's important.

In such cases, your append would generally be more like "add this node as a child for that parent", allow a quick insert since the parent is already known, and a constant time insert if the order of the children doesn't matter.

Otherwise, you might have to go through the tree following whatever rules your application has to find the correct location to place the node.

Upvotes: 2

Related Questions