我已經創建了一個簡單的測試程序,如下所示(省略了錯誤檢查)。ANSI C - 在任意樹中查找節點
我的Tree_Find()和Node_Find()函數似乎能正常工作,但我想知道是否有更高效的方法來實現相同的功能。
Node.h
typedef struct _Node Node;
Node* Node_Create(int nTag);
void Node_Destroy(Node **ppNode);
void Node_Append(Node **ppParent, Node *pChild);
Node* Node_Find(Node *pNode, int nTag);
tree.h中
#include "Node.h"
typedef struct _Tree Tree;
Tree* Tree_Create(void);
void Tree_Destroy(Tree **ppTree);
void Tree_Init(Tree *pTree);
Node* Tree_Find(Tree *pTree, int nTag);
Node.c
#include "Node.h"
struct _Node
{
int nTag;
struct _Node *pFirstChild;
struct _Node *pNextSibling;
};
Node* Node_Create(int nTag)
{
Node *pNode = malloc(sizeof(*pNode));
pNode->nTag = nTag;
pNode->pFirstChild = NULL;
pNode->pNextSibling = NULL;
return pNode;
}
void Node_Destroy(Node **ppNode)
{
Node *pNode = NULL;
if (!ppNode)
return;
if ((pNode = *ppNode) == NULL)
return;
Node_Destroy(&(pNode->pFirstChild));
Node_Destroy(&(pNode->pNextSibling));
free(pNode);
*ppNode = NULL;
}
void Node_Append(Node **ppParent, Node *pChild)
{
Node *pLastChild = NULL;
if (!(*ppParent))
return;
if (!((*ppParent)->pFirstChild))
{
(*ppParent)->pFirstChild = pChild;
return;
}
pLastChild = (*ppParent)->pFirstChild;
while (pLastChild->pNextSibling)
pLastChild = pLastChild->pNextSibling;
pLastChild->pNextSibling = pChild;
}
Node* Node_Find(Node *pNode, int nTag)
{
Node *pNodeFound = NULL;
if (!pNode)
return NULL;
if (pNode->nTag == nTag)
return pNode;
if ((pNodeFound = Node_Find(pNode->pFirstChild, nTag)) == NULL)
pNodeFound = Node_Find(pNode->pNextSibling, nTag);
return pNodeFound;
}
Tree.c
#include "Tree.h"
struct _Tree
{
Node *pRoot;
};
Tree* Tree_Create(void)
{
Tree *pTree = malloc(sizeof(*pTree));
pTree->pRoot = NULL;
return pTree;
}
void Tree_Destroy(Tree **ppTree)
{
Tree *pTree = NULL;
if (!ppTree)
return;
if ((pTree = *ppTree) == NULL)
return;
Node_Destroy(&(pTree->pRoot));
free(pTree);
*ppTree = NULL;
}
void Tree_Init(Tree *pTree)
{
Node *p1 = Node_Create(1);
Node *p2 = Node_Create(2);
Node *p3 = Node_Create(3);
Node *p4 = Node_Create(4);
Node *p5 = Node_Create(5);
Node_Append(&p1, p2);
Node_Append(&p1, p3);
Node_Append(&p3, p4);
Node_Append(&p3, p5);
pTree->pRoot = p1;
}
Node* Tree_Find(Tree *pTree, int nTag)
{
if (!pTree)
return NULL;
return Node_Find(pTree->pRoot, nTag);
}
的main.c
#include "Tree.h"
int main(void)
{
Node *pNodeToFind = NULL;
Tree *pTree = Tree_Create();
Tree_Init(pTree);
pNodeToFind = Tree_Find(pTree, 1);
pNodeToFind = Tree_Find(pTree, 2);
pNodeToFind = Tree_Find(pTree, 3);
pNodeToFind = Tree_Find(pTree, 4);
pNodeToFind = Tree_Find(pTree, 5);
pNodeToFind = Tree_Find(pTree, 6); // Not found!
Tree_Destroy(&pTree);
return 0;
}
您可以避免遞歸。除此之外,它看起來並不需要優化。 –
ANSI C是一個相對模糊的術語。雖然它通常指的是C89,但ANSI也採用了C99 *和* C11。 – oldrinb
以下劃線和大寫字母開頭的名稱保留供實施用於任何目的;避免使用這些名字。在你的代碼中,不要使用前導下劃線; 'typedef struct Node Node;'在C中完全可以(並且在C++中沒有必要)。 –