简体   繁体   English

创建二叉树并通过引用传递节点

[英]Creating binary tree and passing node as pass by reference

I am trying to create a binary tree and i am new to data structure. 我试图创建一个二叉树,我是新来的数据结构。 What i have to do is: 我要做的是:

(1) Take the size of tree (total number of nodes) at terminal. (1)取终端处树的大小(节点总数)。

(2) Then up to size read nodes from the user at terminal (2)然后在终端上最大读取用户的节点

(3) Then create Binary search tree. (3)然后创建二叉搜索树。

Note: I have to pass the node by reference only` in the function call(No other options). 注意:我必须在函数调用中仅通过引用传递节点(没有其他选项)。

It compiles without error but i guess there is any logical problem. 它编译没有错误,但我猜有任何逻辑问题。 It gives segmentation fault when i try to insert second node in for loop (for first it works fine) but compile without errors .I am not able to predict it's due to which line of code? 当我尝试在for循环中插入第二个节点时,它会产生分段错误(首先它可以正常工作),但是编译时没有错误 。我无法预测是由于哪一行代码引起的? When I do: 当我做:

How many  nodes are to be inserted ?
5
enter the nodes 
1 //I am not able to add more nodes
Segmentation fault (core dumped)

Answer in any language c/c++ or even algorithm are welcome. 欢迎使用任何语言的c / c ++甚至算法回答。

My code to do so is : 我这样做的代码是:

#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);
    }

}

I would write it like this (although I wouldn't necessarily use recursion, but maybe you are supposed to...): 我会这样写(尽管我不一定要使用递归,但也许您应该...):

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

And here's how I would write insert_node without recursion: 这是我不递归地编写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);
}

You are getting segmentation fault starting from first input only. 您只能从第一个输入开始出现分段错误。 Let me clear the reason for that. 让我澄清原因。
In insert_beginning function, first line is root = * Node; insert_beginning函数中,第一行是root = * Node; . Here *Node is NULL already. 这里*Node已经为NULL So root would have NULL value also. 因此, root也将具有NULL值。 You expected that root also points to same address as *Node but this is not the case as *Node is pointing to nothing, so root and *Node are still unrelated. 您希望root也指向与*Node相同的地址,但事实并非如此,因为*Node没有指向任何内容,因此root*Node仍然无关。 Now you have allocated the memory to root in previous line, but now you have assigned NULL to root . 现在,您已经在上一行中将内存分配给了root ,但是现在您将NULL分配给了root So previous assigned address to root is lost. 因此,先前分配给root地址会丢失。 So that is the leak memory, Dalibor is talking about. 达利博尔正在谈论的就是泄漏记忆。
Lets go ahead. 让我们继续。
Now root==NULL is checked, which is true, so insert_first_node is called. 现在检查root==NULL ,这是真的,因此insert_first_node There is temp1=Node , which is syntactically wrong. temp1=Node ,这在语法上是错误的。 I think you intended temp1 = *Node . 我认为您打算使用temp1 = *Node But still that is wrong as *Node is NULL , so would be temp1 . 但这仍然是错误的,因为*NodeNULL ,因此将为temp1 Now you are assigning value to NULL object. 现在,您正在将值分配给NULL对象。 So next line gives segmentation fault. 所以下一行给出了分割错误。

The working code can be 工作代码可以是

#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);
    }

}

It seg-faults during the insertion of your first node. 在插入第一个节点期间,它会发生段故障。 If it was during the second insert, you would see the message "enter the nodes" twice. 如果是在第二次插入过程中,您将看到两次“输入节点”消息。

Now to the reason. 现在到原因了。 In the function insert_beginning, the first if statement does not compare root to NULL, but sets it to NULL. 在函数insert_beginning中,第一个if语句不将root与NULL比较,而是将其设置为NULL。 Since NULL is treated as false, the code inside the if is not evaluated and the execution moves to the second if statement. 由于将NULL视为false,因此不会评估if中的代码,并且执行将移至第二条if语句。 In it, you're trying to access freq field of root, which is set to NULL from the first if statement. 在其中,您尝试访问root的freq字段,该字段从第一个if语句设置为NULL。 So you are trying to dereference NULL pointer, which leads to the seg-fault. 因此,您尝试取消引用NULL指针,这会导致seg-fault。

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

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