创建二叉树并将节点作为引用传递

时间:2014-03-01 21:14:49

标签: c data-structures tree binary-tree

我正在尝试创建一个二叉树,我是数据结构的新手。 我要做的是:

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

}

3 个答案:

答案 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;。此处*NodeNULL。因此root也会有NULL值。您希望root也指向与*Node相同的地址,但事实并非如此,因为*Node没有指向任何内容,因此root*Node仍然无关。现在,您已将内存分配到上一行的root,但现在您已将NULL分配给root。因此,先前分配给root的地址将丢失。这就是泄漏记忆,Dalibor正在谈论 让我们继续吧 现在检查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);
    }

}

答案 2 :(得分:0)

在插入第一个节点时出现seg-fault。如果是在第二次插入期间,您将看到消息“输入节点”两次。

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