繁体   English   中英

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

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

我试图创建一个二叉树,我是新来的数据结构。 我要做的是:

(1)取终端处树的大小(节点总数)。

(2)然后在终端上最大读取用户的节点

(3)然后创建二叉搜索树。

注意:我必须在函数调用中仅通过引用传递节点(没有其他选项)。

它编译没有错误,但我猜有任何逻辑问题。 当我尝试在for循环中插入第二个节点时,它会产生分段错误(首先它可以正常工作),但是编译时没有错误 。我无法预测是由于哪一行代码引起的? 当我做:

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

}

我会这样写(尽管我不一定要使用递归,但也许您应该...):

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

您只能从第一个输入开始出现分段错误。 让我澄清原因。
insert_beginning函数中,第一行是root = * Node; 这里*Node已经为NULL 因此, root也将具有NULL值。 您希望root也指向与*Node相同的地址,但事实并非如此,因为*Node没有指向任何内容,因此root*Node仍然无关。 现在,您已经在上一行中将内存分配给了root ,但是现在您将NULL分配给了root 因此,先前分配给root地址会丢失。 达利博尔正在谈论的就是泄漏记忆。
让我们继续。
现在检查root==NULL ,这是真的,因此insert_first_node temp1=Node ,这在语法上是错误的。 我认为您打算使用temp1 = *Node 但这仍然是错误的,因为*NodeNULL ,因此将为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);
    }

}

在插入第一个节点期间,它会发生段故障。 如果是在第二次插入过程中,您将看到两次“输入节点”消息。

现在到原因了。 在函数insert_beginning中,第一个if语句不将root与NULL比较,而是将其设置为NULL。 由于将NULL视为false,因此不会评估if中的代码,并且执行将移至第二条if语句。 在其中,您尝试访问root的freq字段,该字段从第一个if语句设置为NULL。 因此,您尝试取消引用NULL指针,这会导致seg-fault。

暂无
暂无

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

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