c - 在树中插入(键,值)时,节点不形成树结构
问题描述
我正在尝试创建 avl 树,它从文件中一对一地读取(键,值)并根据键的数据形成树。
首先,将元组读入键和值并将它们传递给创建函数,在该函数中我使用结构初始化了一个树
typedef struct AVLTree{
int size; // count of items in avl tree
AVLTreeNode *root; // root
} AVLTree;
AVLTree *newAVLTree()
{
AVLTree *T;
T = malloc(sizeof (AVLTree));
assert (T != NULL);
T->size = 0;
T->root = NULL;
return T;
}
然后我最初将树的根的值为 NULL 的值分配给结构如下所示的 AVLTreeNode:
typedef struct AVLTreeNode {
int key; //key of this item
int value; //value (int) of this item
int height; //height of the subtree rooted at this node
struct AVLTreeNode *parent; //pointer to parent
struct AVLTreeNode *left; //pointer to left child
struct AVLTreeNode *right; //pointer to right child
} AVLTreeNode;
//data type for AVL trees
typedef struct AVLTree{
int size; // count of items in avl tree
AVLTreeNode *root; // root
} AVLTree;
// create a new AVLTreeNode
AVLTreeNode *newAVLTreeNode(int k, int v )
{
AVLTreeNode *new;
new = malloc(sizeof(AVLTreeNode));
assert(new != NULL);
new->key = k;
new->value = v;
new->height = 0; // height of this new node is set to 0
new->left = NULL; // this node has no child
new->right = NULL;
new->parent = NULL; // no parent
return new;
}
现在,对于我从文件中读取的每个键值对,我将其传递给 create 函数并检查以下 3 个条件:
void insert_in_tree(int key, int value, struct AVLTreeNode **node){
// if the tree is empty
if(*node == NULL){
node = newNode;
}
// insert on left if the data in the key is less than the data in the node.
else if (key<(*node)->key){
insert_in_tree(key,value,&(*node)->left);
}
// insert on right if the data in the key is greater than the data in the node.
else if(key>(*node)->key)
{
insert_in_tree(key,value,&(*node)->right);
}
}
PS:不要担心 newAVLTreeNode 中的“值”部分,因为稍后我将使用它来处理重复项。
使用上面的代码,我希望树会形成,但这并没有发生。经过进一步调查和调试,我发现虽然 insert_in_tree 使用新的键和值传递,但节点也是新的,而不是已经创建的节点。
AVLTree *CreateAVLTree(const char *filename)
{
//Inititalising a new tree
AVLTree *tree = newAVLTree();
// initialising the head to root of tree i.e. null
AVLTreeNode *head = tree->root;
int key, value;
FILE* file = fopen(filename, "r"); // open a file
if(file == NULL) {
return 1; // error checking
}
while (fscanf (file, " (%d,%d)", &key, &value) == 2) // check for number of conversions
// space added here ^
{
insert_in_tree(key, value, &head);
//printf("%d,%d\n", key, value);
}
fclose(file);
return tree;
}
int main() //sample main for testing
{
AVLTree *tree1;
tree1=CreateAVLTree("File1.txt");
//PrintAVLTree(tree1);
return 0;
}
解决方案
米哈伊尔快到了,但没有发现内存泄漏。我在下面更正:
void insert_in_tree(int key, int value, struct AVLTreeNode **node){
// if the tree is empty
if(*node == NULL){
*node = newAVLTreeNode(key, value);
}
// insert on left if the data in the key is less than the data in the node.
else if (key<(*node)->key){
insert_in_tree(key,value,&(*node)->left);
}
// insert on right if the data in the key is greater than the data in the node.
else if(key>(*node)->key)
{
insert_in_tree(key,value,&(*node)->right);
}
}
作为修复的摘要:
您需要将指针传递给放置新分配节点的位置,因为 C 通过值传递。这就是所谓的“双指针”。
您在每次递归调用时都分配了内存,但只有在知道插入位置时才需要这样做。
推荐阅读
- c# - 尝试生成有效数字时在 C# 中计算了错误的总和
- mongodb - 使用 geoWithin 的 MongoDB 查询工作错误
- c# - .net 5 中的记录类型用法是什么?
- css - 如何防止网格区域的内部内容向下突出?
- python - 使用自然三次样条外推时的曲率
- excel - EXCEL:两栏,2轴直方图
- python - 给定系列列表时,熊猫“未正确调用DataFrame构造函数”
- windows - 达到一定计数值后自动删除子文件夹中的文件
- ruby - 用空格分割的 Ruby 字符串作为输入删除的不仅仅是空格
- microsoft-graph-api - 我们可以使用自定义团队模板来请求新的团队团队吗(失败)