链接列表集成到树结构中

时间:2011-11-19 20:00:52

标签: c tree linked-list

我正在创建一个树结构,该树结构的每个节点都包含一个链接的数据列表(数字)。现在,在我的脑海中,这意味着,每个链接的链接显然需要有一个与它们相关联的头,这样我就可以访问它们中的数据并循环,显示该TreeNode的所有数字。问题是,我碰到了一堵砖墙,真的不知道从我现在的位置采取什么步骤(见下文)。我需要为每个链表返回一个头,对于每个,TreeNode,我不确定如何。

下面是我到目前为止的代码,此时,它将名称添加到节点,并将一个数字添加到列表中,但是在列表中添加多个数字,我不确定下一步是什么步骤采取,然后如何返回一个项目,以允许我(及时)打印功能循环。

typedef struct ListNode {
char            *number;
struct ListNode *next;
}ListNode;

typedef struct TreeNode {
char            *name;
ListNode        *numbers;
struct TreeNode *left;
struct TreeNode *right;
}TreeNode;

TreeNode* AddNode(TreeNode *, char *, char *);
TreeNode* SearchTree(TreeNode *root, char *search);
void N_Print(TreeNode *root);

int main(void) {
char my_string[50], name[25], number[25];
TreeNode *root = NULL;
while ((fgets(my_string, 50, stdin)) != NULL) {
    if (my_string[0] == '.')
        break;      
sscanf(my_string, "%s %s", name, number); 
root = AddNode(root, name, number);  
}   
return 0;
}

TreeNode* AddNode(TreeNode *root, char *name, char *number) {
int comparison;
if ( root == NULL) {
    root = (TreeNode *)malloc(sizeof(TreeNode));
    root->numbers = (ListNode *)malloc(sizeof(ListNode));
    root->name = strdup(name); root->numbers->number = strdup(number);
    root->left = root->right = NULL;
    root->numbers->next = NULL;
}else if (( comparison = strcmp(name, root->name)) < 0 )
    root->left = AddNode(root->left, name, number);
else if (comparison > 0) {
    root->right = AddNode(root->right, name, number);
} else if (comparison == 0 ) {
    root->numbers->number = strdup(number);
    root->numbers->next = NULL;
}
return root;
}

2 个答案:

答案 0 :(得分:0)

希望我能正确理解你的问题......

我建议您在列表中添加另一级别的间接...您可以创建一个List结构,该结构包含List的头部,尾部等,并添加List(或指向一个的指针)而不是ListNode *到TreeNode结构。这样你就可以拥有一个List* getList(TreeNode*)并且具有直接在返回的列表上运行的函数(在我看来这更干净)。这意味着您的列表实现将与您的树完全分离,这意味着您可以在此项目之外轻松使用它。

另一种方法是将List完全封装在TreeNode结构中,这是我认为你正在尝试做的事情。要添加到列表,您可能需要一个函数addNumber(TreeNode*, char*),其他列表操作函数将以类似方式完成。他们只需要一个提供对列表的访问的TreeNode的引用或指针。

要执行您要执行的操作,如果您有ListNode*,则您已有权访问TreeNode*

TreeNode* tn = something; 
for(ListNode* ln = tn->numbers; ln != NULL; ln = ln->next) {
    // do something here (print, etc.) with ln->number
}

您可以轻松地将此选项放入以TreeNode*作为参数的函数中。这是你想要做的吗?

答案 1 :(得分:0)

我制作一个基本的打印功能来打印树节点。我还修改了函数原型以使生活更轻松:)

我希望这会有所帮助。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>



typedef struct ListNode ListNode;
typedef struct TreeNode TreeNode;


struct ListNode {
    char            *number;
    ListNode        *next;
};

struct TreeNode {
    char            *name;
    ListNode        *numbers;
    TreeNode        *left;
    TreeNode        *right;
};

TreeNode    *new_tree_node(char *name);
ListNode    *new_list_node(char *number);

void ListNode_AddNode(ListNode **plist, char *number);
void TreeNode_AddNode(TreeNode **proot, char *name, char *number);

void ListNode_Print(ListNode *list);
void TreeNode_Print(TreeNode *root);
TreeNode * TreeNode_FindNode(TreeNode * root,char *name);

/*________________________________________________________________________________________________
*/
int main(void) {
    char my_string[50], name[25], number[25];
    TreeNode *root = NULL;
    while ((fgets(my_string, 50, stdin)) != NULL) {
        if (my_string[0] == '.')
            break;      
        sscanf(my_string, "%s %s", name, number); 
        TreeNode_AddNode(&root, name, number);  
    }

    printf("PRINTING TREENODE:\n");
    TreeNode_Print(root);
    printf("========================================================================= DONE\n\n");

    printf("PRINTING (jaguar's numbers) :\n");

    TreeNode *jaguar = TreeNode_FindNode(root,"jaguar");
    if(jaguar)
        ListNode_Print(jaguar->numbers);
    else
        printf("jaguar node not found");

    printf("\n========================================================================= DONE\n\n");
    return 0;
}
/*________________________________________________________________________________________________
*/
TreeNode *new_tree_node(char *name){
    TreeNode *tree = calloc(1,sizeof(TreeNode));

    if ( tree ) {
        tree->name=strdup(name);
    }
    return tree;
}

ListNode * new_list_node(char *number){
    ListNode *list = calloc(1,sizeof(ListNode));
    if ( list ) {
        list->number=strdup(number);
    }
    return list;
}

void ListNode_AddNode(ListNode **plist, char *number){
    ListNode *list = *plist;
    if( !list ) {
        list = new_list_node (number);
        *plist = list;
    }
    else{
        ListNode_AddNode(&list->next,number);
    }
    return ;
}

void TreeNode_AddNode(TreeNode **proot, char *name, char *number) {

    TreeNode *root = *proot;

    if ( !root ) {
        root    = new_tree_node(name);
        *proot  = root;
    }else {
        int comparison = strcmp(name, root->name);

        if (comparison < 0 ){
            TreeNode_AddNode(&root->left, name, number);
            return;
        }
        if (comparison > 0) {
            TreeNode_AddNode(&root->right, name, number);
            return;
        }
    }

    ListNode_AddNode ( &root->numbers,number);
    return ;
}

void ListNode_Print(ListNode *list){
    if(!list) return;
    printf("%s ",list->number);
    ListNode_Print (list->next);
}

void print_tatbs(int n){
    while( n ){
        n--;
        putchar('\t');
    }
}
void TreeNode_Print(TreeNode *root){
    static int tree_deep = 0;
    if( !root ) 
        return;
    print_tatbs(tree_deep);
    printf("Node: %s, Numbers: ",root->name);
    ListNode_Print(root->numbers);
    printf("\n");


    if(root->left){
        tree_deep++;
        print_tatbs(tree_deep);
        printf("Left:\n");
        TreeNode_Print(root->left);
        tree_deep--;
    }
     if(root->right){
        tree_deep++;
        print_tatbs(tree_deep);
        printf("Right:\n");
        TreeNode_Print(root->right);
        tree_deep--;
    }
}


TreeNode * TreeNode_FindNode(TreeNode * root,char *name){

    if(!root) return root;

    int comparison = strcmp(name, root->name);

    if (comparison < 0 )
        return TreeNode_FindNode(root->left, name);

    if (comparison > 0)
        return TreeNode_FindNode(root->right, name);

   return root; 
}