我查看了几篇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属性,程序将崩溃。在我从中借用代码的程序中,这些属性的打印没有错误。根目录仍然正确插入,可以打印它的属性。
非常感谢任何关于我不正确行为的见解。
答案 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
既然我们已经在这里了,那么有人可以解释为什么会出现问题/如何以这种方式正确地循环数组?