简体   繁体   English

二叉树插入错误

[英]Binary Tree Insertion Error

I looked at several BST Insert articles but none of them were structured the same as mine or encountered the same problem. 我看了几篇BST插入文章,但没有一篇文章的结构与我的相同,也没有遇到相同的问题。

My problem is my Binary Tree isn't being built correctly. 我的问题是我的二叉树没有正确构建。 It's really strange because I'm copy+pasting most of the code from a previous project where it works fine, the only difference is the data the nodes contain, and the condition for looping through the tree uses strcmp rather than integer comparison. 真的很奇怪,因为我要复制并粘贴以前项目正常工作的大多数代码,唯一的区别是节点包含的数据,并且遍历树的条件使用strcmp而不是整数比较。

This is my insert function: 这是我的插入功能:

//insert parameter node data into a Binary Tree
TreeNodePtr insertNode(BinaryTree bst, Record d)
{
    //if root is null insert into root
    if(bst.root == NULL)
    {
        bst.root = (TreeNodePtr) malloc(sizeof(TreeNode));
        bst.root->data = d;
        bst.root->left = NULL;
        bst.root->right = NULL;
        return bst.root;
    }

    //we need to traverse the tree so declare a pointer "curr" to do so
    TreeNodePtr curr = (TreeNodePtr) malloc(sizeof(TreeNode));
    curr = bst.root;

    //loop until we find an appropriate empty space or a match (no duplicates)
    while (strcmp(d.lastName, curr->data.lastName) != 0)
    {
        if (strcmp(d.lastName, curr->data.lastName) < 0)
        { // if left
            if(curr->left==NULL) 
            {
                curr->left = (TreeNodePtr) malloc(sizeof(TreeNode));
                curr->left->data = d;
                curr->left->left = NULL;
                curr->left->right = NULL;
                return bst.root;
            }
            curr=curr->left;
        }
        else if (strcmp(d.lastName, curr->data.lastName) > 0)
        { // try right
            if(curr->right==NULL)
            {
                curr->right = (TreeNodePtr) malloc(sizeof(TreeNode));
                curr->right->data = d;
                curr->right->left = NULL;
                curr->right->right = NULL;
                return bst.root;
            }
            curr=curr->right;
        }
    }

    return bst.root;
}

Here is the code in the main function which uses the insert function to build the tree (note that records is a correctly populated array, each index containing one node's data): 以下是main函数中的代码,该函数使用insert函数构建树(请注意,记录是一个正确填充的数组,每个索引都包含一个节点的数据):

//declare BST and build it
BinaryTree phoneTree;
phoneTree.root = NULL;

for (int i=0; i < sizeof(records) / sizeof(Record); i++)
{
    Record tmpRecord;
    tmpRecord.firstName = records[i].firstName;
    tmpRecord.lastName = records[i].lastName;
    tmpRecord.phoneNum = records[i].phoneNum;
    phoneTree.root = insertNode(phoneTree, tmpRecord);
}

And for reference, here are the tree structs: 作为参考,下面是树结构:

//phone data record struct
typedef struct
{
    char *firstName;
    char *lastName;
    char *phoneNum;
}Record;

//define the tree node which contains the data
typedef struct treeNode
{
    Record data;
    struct treeNode *left,*right;
}TreeNode,*TreeNodePtr;

//define binary tree struct
typedef struct
{
    TreeNodePtr root;
}BinaryTree;

I've been staring at the program that works and comparing it to this program for about 5 hours now and I can't figure out what's going wrong. 我一直在盯着该程序,并将它与该程序进行了大约5个小时的比较,但我无法弄清楚出了什么问题。 I know the tree isn't populated correctly because if i try to print phoneTree.root->right.data or phoneTree.root->left.data attributes, the program crashes. 我知道树没有正确填充,因为如果尝试打印phoneTree.root-> right.data或phoneTree.root-> left.data属性,程序将崩溃。 In the program I'm borrowing the code from, these attributes are printed without error. 在我从中借用代码的程序中,这些属性被正确打印。 The root is still inserted correctly and it's attributes can be printed. 仍然可以正确插入根,并且可以打印其属性。

Any insight as to what I'm doing incorrectly is greatly appreciated. 非常感谢您对我做错了什么的任何见解。

There is one definite mistake, which could be causing you problems. 有一个确定的错误,这可能会导致您遇到问题。 You need to pass "bst" by reference, so that the function can modify "bst.root". 您需要通过引用传递“ bst”,以便函数可以修改“ bst.root”。 Try rewriting the function as: 尝试将函数重写为:

 TreeNodePtr insertNode(BinaryTree* bst, Record d)

and use "bst->" in place of "bst." 并使用“ bst->”代替“ bst”。

You said that it worked with integers. 您说过它适用于整数。 Now that may be a clue to another mistake. 现在,这可能是另一个错误的线索。 Your record contains only pointers to strings. 您的记录仅包含指向字符串的指针。 Do these pointers remain valid throughout the lifetime of the tree? 这些指针在树的整个生命周期中都保持有效吗? Maybe you need to make copies of the strings within the record. 也许您需要在记录中复制字符串。

Couple of other minor things: 其他几项小事:

//we need to traverse the tree so declare a pointer "curr" to do so
TreeNodePtr curr = (TreeNodePtr) malloc(sizeof(TreeNode));
curr = bst.root;

malloc is redundant here, the result is immediately overwritten. malloc在这里是多余的,结果将立即被覆盖。

And: 和:

    }
    else if (strcmp(d.lastName, curr->data.lastName) > 0)
    { // try right

you can replace this with "} else {" as you already did this strcmp operation. 您可以使用strcmp操作将其替换为“} else {”。

Thanks for all the great tips, they've all contributed to my understanding of memory management in C. 感谢所有出色的技巧,它们都为我对C语言中的内存管理的理解做出了贡献。

Strangely, I found the problem is actually rooted in my array for loop. 奇怪的是,我发现问题实际上根源于我的循环数组。 I found the method of using sizeof(array) / sizeof(arraydatatype) from multiple sources on the internet and this site so I attempted it, but it doesn't work the way I tried. 我从互联网和此站点的多个来源中找到了使用sizeof(array)/ sizeof(arraydatatype)的方法,因此我尝试了它,但是它不起作用。 In: 在:

for (int i=0; i < sizeof(records) / sizeof(Record); i++)
{
    Record tmpRecord;
    tmpRecord.firstName = records[i].firstName;
    tmpRecord.lastName = records[i].lastName;
    tmpRecord.phoneNum = records[i].phoneNum;
    phoneTree.root = insertNode(phoneTree, tmpRecord);
}

I replaced "i < sizeof(records) / sizeof(Record)" with just"i < 3" (array should only have 3 elements at this point), and everything worked as it should. 我将“ i <sizeof(records)/ sizeof(Record)”替换为“ i <3”(数组此时仅应包含3个元素),并且一切正常。 It's a really dumb source of the problem, but funny that despite all the answers provided none mentioned it :p 这确实是一个愚蠢的问题根源,但有趣的是,尽管提供了所有答案,但都没有提及它:p

Since we're already here, can anyone explain why that was going wrong / how to properly loop through an array in such a manner? 既然我们已经在这里,谁能解释为什么会出错/如何以这种方式正确遍历数组?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM