二叉树插入错误

时间:2015-04-21 19:22:00

标签: c binary-search-tree

我查看了几篇BST插入文章,但没有一篇与我的结构相同或遇到同样的问题。

我的问题是我的二叉树没有正确构建。这真的很奇怪,因为我复制+粘贴了以前项目中的大多数代码,它工作正常,唯一的区别是节点包含的数据,循环遍历树的条件使用strcmp而不是比整数比较。

这是我的插入功能:

//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;
}

这是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);
}

供参考,以下是树形结构:

//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;

我一直在盯着有效的程序并将其与此程序进行比较约5个小时,我无法弄清楚出了什么问题。我知道树没有正确填充,因为如果我尝试打印phoneTree.root-&gt; right.data或phoneTree.root-&gt; left.data属性,程序将崩溃。在我从中借用代码的程序中,这些属性的打印没有错误。根目录仍然正确插入,可以打印它的属性。

非常感谢任何关于我不正确行为的见解。

2 个答案:

答案 0 :(得分:3)

有一个明确的错误,可能会导致你的问题。您需要通过引用传递“bst”,以便该函数可以修改“bst.root”。尝试将函数重写为:

 TreeNodePtr insertNode(BinaryTree* bst, Record d)

并使用“bst-&gt;”代替“bst。”

你说它适用于整数。现在这可能是另一个错误的线索。您的记录仅包含指向字符串的指针。这些指针在树的整个生命周期内是否仍然有效?也许你需要在记录中复制字符串。

其他一些小事:

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

malloc在这里是多余的,结果会立即被覆盖。

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

你可以用“} else {”替换它,因为你已经完成了这个strcmp操作。

答案 1 :(得分:0)

感谢所有伟大的提示,他们都为我对C中的内存管理的理解做出了贡献。

奇怪的是,我发现问题实际上是根据我的数组for循环。我找到了在互联网和本网站上使用来自多个来源的sizeof(array)/ sizeof(arraydatatype)的方法,所以我尝试了它,但它不能像我尝试的那样工作。在:

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&lt; 3”替换了“i&lt; sizeof(records)/ sizeof(Record)”(此时数组应该只有3个元素),一切都按原样运行。这是一个非常愚蠢的问题来源,但有趣的是,尽管提供了所有的答案没有提到它:p

既然我们已经在这里了,那么有人可以解释为什么会出现问题/如何以这种方式正确地循环数组?