我正在尝试创建一个二叉树,我是数据结构的新手。 我要做的是:
(1)取终端的树的大小(节点总数)。
(2)然后在终端
处调整来自用户的读取节点的大小(3)然后创建二进制搜索树。
注意:我必须在函数调用中仅通过引用传递节点(没有其他选项)。
它编译没有错误,但我猜有任何逻辑问题。当我尝试在for循环中插入第二个节点时,它给出了分段错误(首先它工作正常)但编译没有错误 .I我无法预测它是由于哪行代码? 当我这样做时:
How many nodes are to be inserted ?
5
enter the nodes
1 //I am not able to add more nodes
Segmentation fault (core dumped)
用任何语言回答c / c ++甚至算法都是受欢迎的。
我这样做的代码是:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node * left, * right;
};
typedef struct node node;
/////////////////////////////////////////////////////////////Function definitions //////////////////////////////////////////////////
insert_first_node(int data, node * * Node)
{
node * temp1 ;
temp1 = Node;
temp1= (node * ) malloc(sizeof(node));
temp1 -> freq = data;
temp1 -> left = NULL;
temp1 -> right = NULL;
}
////////////////////////////////////////////////////////////////////
insert_beginning(int data, node * * Node)
{
root = * Node;
root = (node * ) malloc(sizeof(node));;
if (root ==NULL)
{
insert_first_node(data, & root);
}
if (data <= root -> freq)
{
insert_beginning(data, & root -> left);
} else
{
insert_beginning(data, & root -> right);
}
*Node = root;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
main()
{
int i, size, data;
node * head;
head = NULL;
printf("How many nodes are to be inserted ?\n");
scanf("%d", & size);
for (i = 1; i <= size; i++)
{
printf("enter the nodes \n");
scanf("%d", & data);
insert_beginning(data, & head);
}
}
答案 0 :(得分:2)
我会这样写(虽然我不一定会使用递归,但也许你应该......):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node
{
int freq;
struct Node *left;
struct Node *right;
} Node;
///////////////////////////////////////////////////////////
// Function definitions //
///////////////////////////////////////////////////////////
int insert_leaf_node(int freq, Node **parent_ptr)
{
Node *node;
if ((node = malloc(sizeof *node)) == NULL)
return -1;
node->freq = freq;
node->left = NULL;
node->right = NULL;
*parent_ptr = node;
return 0;
}
///////////////////////////////////////////////////////////
int insert_node(int freq, Node **parent_ptr)
{
Node *node = *parent_ptr;
if (node == NULL) {
return insert_leaf_node(freq, parent_ptr);
}
else if (freq <= node->freq) {
return insert_node(freq, &node->left);
}
else {
return insert_node(freq, &node->right);
}
}
///////////////////////////////////////////////////////////
int main()
{
int i, size, freq;
Node *root = NULL;
printf("How many nodes are to be inserted ?\n");
scanf("%d", &size);
for (i = 0; i < size; i++) {
printf("enter the freq of node %d\n", i+1);
scanf("%d", &freq);
insert_node(freq, &root);
}
return 0;
}
这就是我如何在没有递归的情况下编写insert_node
:
int insert_node(int freq, Node **parent_ptr)
{
Node *node;
while ((node = *parent_ptr) != NULL) {
parent_ptr = (freq <= node->freq) ? &node->left : &node->right;
}
return insert_leaf_node(freq, parent_ptr);
}
答案 1 :(得分:1)
您仅从第一个输入开始出现分段错误。让我说清楚原因。
在insert_beginning
函数中,第一行是root = * Node;
。此处*Node
已NULL
。因此root
也会有NULL
值。您希望root也指向与*Node
相同的地址,但事实并非如此,因为*Node
没有指向任何内容,因此root
和*Node
仍然无关。现在,您已将内存分配到上一行的root
,但现在您已将NULL
分配给root
。因此,先前分配给root
的地址将丢失。这就是泄漏记忆,Dalibor正在谈论
让我们继续吧
现在检查root==NULL
,这是真的,因此调用insert_first_node
。有temp1=Node
,这在语法上是错误的。我认为你打算temp1 = *Node
。但仍然是错误的,因为*Node
是NULL
,所以temp1
也是如此。现在您要为NULL
对象赋值。所以下一行给出了分段错误。
工作代码可以是
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node * left, * right;
};
typedef struct node node;
/////////////////////////////////////////////////////////////Function definitions //////////////////////////////////////////////////
void insert_first_node(int data, node * * Node,int direction)
{
node * temp1 = (node * ) malloc(sizeof(node));
temp1 -> freq = data;
temp1 -> left = NULL;
temp1 -> right = NULL;
if(*Node == NULL)
*Node = temp1;
else if(direction == 1)
(*Node)->right = temp1;
else
(*Node)->left = temp1;
}
////////////////////////////////////////////////////////////////////
void insert_beginning(int data, node * * Node)
{
node *root;
root = * Node;
if (root == NULL)
{
insert_first_node(data,Node,0);
return;
}
if (data <= root -> freq)
{
if(root->left == NULL)
insert_first_node(data,&root,0);
else
insert_beginning(data,&root->left);
} else
{
if(root->right == NULL)
insert_first_node(data,&root,1);
else
insert_beginning(data,&root->right);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
main()
{
int i, size, data;
node * head;
head = NULL;
printf("How many nodes are to be inserted ?\n");
scanf("%d", & size);
for (i = 1; i <= size; i++)
{
printf("enter the nodes \n");
scanf("%d", & data);
insert_beginning(data, & head);
}
}
答案 2 :(得分:0)
在插入第一个节点时出现seg-fault。如果是在第二次插入期间,您将看到消息“输入节点”两次。
现在到了原因。在函数insert_beginning中,第一个if语句不将root与NULL进行比较,而是将其设置为NULL。由于NULL被视为false,因此不会评估if中的代码,执行将移至第二个if语句。在其中,您正在尝试访问root的freq字段,该字段从第一个if语句设置为NULL。所以你试图取消引用NULL指针,这会导致seg-fault。