在检查bst中的节点是否为空之后,当我尝试为bst的成员分配值时出现分段错误

#include <stdio.h>
#include <stdlib.h>

typedef int Data_Item;

struct Bst2_Node
{
  int key;
  Data_Item data;
  struct Bst2_Node *left, *right;
};
typedef struct Bst2_Node BStree2_node;
typedef BStree2_node** BStree2;


BStree2 bs_tree2_ini(void)
{
  BStree2 bst;
  bst =(BStree2)malloc(sizeof(BStree2_node *));
  *bst=NULL;
  return bst;
}

void bs_tree2_insert(BStree2 bst, int key, Data_Item data)
{
  if(*bst==NULL)
{
    (*bst)->key = key;
    (*bst)->data = data;
}

  else if(key < (*bst)->key)
{
    bs_tree2_insert(&(*bst)->left, key, data);
}
  else if(key > (*bst)->key)
{
    bs_tree2_insert(&(*bst)->right, key, data);
}
  else return;
}

Data_Item *bs_tree2_search(BStree2 bst, int key)
{
    if(key==(*bst)->key)
{
    return &(*bst)->data;
}
    else return NULL;
}

void bs_tree2_traversal(BStree2 bst)
{
    if(!*bst) return;

    bs_tree2_traversal(&(*bst)->left);
    printf("%d\n", (*bst)->data);
    bs_tree2_traversal(&(*bst)->right);
}

static void btree_free(BStree2_node *bt)
{
   if(bt == NULL) return;
   btree_free(bt->left);
   btree_free(bt->right);
   free(bt);
}

void bs_tree2_free(BStree2 bst)
{
   btree_free(*bst);
   free(bst);
}

int main(int argc, char** argv)
{
 int a;
 int b;
 a = 1;
 b = 2;
 BStree2 bst = bs_tree2_ini();
 printf(".");
 bs_tree2_insert(bst, a, b);
 //bs_tree2_traversal(bst);
 bs_tree2_free(bst);
 return (0);
}

另外,当我初始化一个指向null的指针时,是否也意味着内容也为null? 抱歉,格式化

===============>>#1 票数:1 已采纳

当我初始化一个指向null的指针时,是否也意味着内容也为null?

否。当您将指针初始化为null时,它将其设置为指向零。 您仍然可以访问空指针并从中获取成员, 但是在大多数操作系统上,这将导致崩溃,例如分段错误

崩溃是因为您将指针分配给指针,请参见typedef BStree2_node** BStree2 ; 双星号表示它是双指针类型(指向指针的指针)。

然后,在bs_tree2_ini()中将内容初始化为NULL(因此,您有一个指向NULL的有效指针bs_tree2_ini() 然后,在bs2_tree2_insert()取消引用第二个指针。

如果(* bst)为NULL,则不应设置其任何成员。 它不是有效的指针。 您需要首先分配一个结构。 例如,

if ((*bst)==NULL)
{
    (*bst) = (BStree2_node*)malloc(sizeof(BStree2_node));
    if ((*bst) == NULL)
    {
        // allocation failed.
    }
    else
    {
        // allocation success. set data members here.
    }
}

===============>>#2 票数:1

我不知道为什么这几天教员们会感到满意,但不是必须的。 NULL值与其他值一样,是一个很好的测试值。 考虑这样的实现,我强烈建议您花大量时间盯着研究,研究调试,如果可能的话,单步调试器:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef int Data_Item;
typedef struct BST_Node
{
    int key;
    Data_Item data;
    struct BST_Node *left, *right;
} BST_Node;

typedef enum
{
    BST_TRAVERSE_PREORDER,
    BST_TRAVERSE_INORDER,
    BST_TRAVERSE_POSTORDER
} BST_TRAVERSE_TYPE;

// allocate a new BST node and copy in the passed data
BST_Node *BST_newnode(int key, Data_Item data)
{
    BST_Node *p = malloc(sizeof(*p));
    p->left = p->right = NULL;
    p->key = key;
    p->data = data;
    return p;
}

// insert. recurses until we reach a null node, then performs
//  the insertion at that node pointer. initial invoke is done
//  using the address of the root of our tree.
//
// note: this implementation does NOT allow duplicates
void BST_insert(struct BST_Node** p, int key, Data_Item data)
{
    if (*p == NULL)
    {
        *p = BST_newnode(key, data);
    }
    else if (key < (*p)->key)
    {
        BST_insert(&(*p)->left, key, data);
    }

    else if ((*p)->key < key)
    {
        BST_insert(&(*p)->right, key, data);
    }
}

// traverses based on traversal selection type
void BST_traverse(BST_Node* p, BST_TRAVERSE_TYPE tt,
                  void (*pfn)(int, Data_Item* data))
{
    if (!p)
        return;

    switch (tt)
    {
        case BST_TRAVERSE_PREORDER:
            pfn(p->key, &p->data);
            BST_traverse(p->left, tt, pfn);
            BST_traverse(p->right,tt, pfn);
            break;

        case BST_TRAVERSE_INORDER:
            BST_traverse(p->left, tt, pfn);
            pfn(p->key, &p->data);
            BST_traverse(p->right,tt, pfn);
            break;

        case BST_TRAVERSE_POSTORDER:
            BST_traverse(p->left, tt, pfn);
            BST_traverse(p->right,tt, pfn);
            pfn(p->key, &p->data);
            break;
    }
}

// deletes a node AND all its children
void BST_delete_all(BST_Node** p)
{
    // do nothing on a null pointer
    if (!*p)
        return;

    BST_delete_all(&(*p)->left);
    BST_delete_all(&(*p)->right);
    free(*p);
    *p = NULL;
}


// my print function
void print_data(int key, Data_Item* pData)
{
    printf("Key %.2d ==> %d\n", key, *pData);
}

int main(int argc, char *argv[])
{
    srand((unsigned)time(0));
    BST_Node* root = NULL;
    for (int i=0;i<16;++i)
        BST_insert(&root, rand()%50, i);

    printf("Preorder Traversal\n");
    printf("=================\n");
    BST_traverse(root, BST_TRAVERSE_PREORDER, &print_data);

    printf("\nInorder Traversal\n");
    printf("=================\n");
    BST_traverse(root, BST_TRAVERSE_INORDER, &print_data);

    printf("\nPostorder Traversal\n");
    printf("=================\n");
    BST_traverse(root, BST_TRAVERSE_POSTORDER, &print_data);

    // delete the tree
    BST_delete_all(&root);

    return EXIT_SUCCESS;
};

样本输出

Preorder Traversal
=================
Key 30 ==> 0
Key 07 ==> 2
Key 05 ==> 4
Key 04 ==> 5
Key 03 ==> 8
Key 24 ==> 3
Key 17 ==> 7
Key 10 ==> 14
Key 16 ==> 15
Key 19 ==> 9
Key 29 ==> 12
Key 43 ==> 1
Key 40 ==> 10
Key 39 ==> 11

Inorder Traversal
=================
Key 03 ==> 8
Key 04 ==> 5
Key 05 ==> 4
Key 07 ==> 2
Key 10 ==> 14
Key 16 ==> 15
Key 17 ==> 7
Key 19 ==> 9
Key 24 ==> 3
Key 29 ==> 12
Key 30 ==> 0
Key 39 ==> 11
Key 40 ==> 10
Key 43 ==> 1

Postorder Traversal
=================
Key 03 ==> 8
Key 04 ==> 5
Key 05 ==> 4
Key 16 ==> 15
Key 10 ==> 14
Key 19 ==> 9
Key 17 ==> 7
Key 29 ==> 12
Key 24 ==> 3
Key 07 ==> 2
Key 39 ==> 11
Key 40 ==> 10
Key 43 ==> 1
Key 30 ==> 0

  ask by user2287442 translate from so

未解决问题?本站智能推荐:

2回复

如何在C中的声明之外为字符串分配值? 总线错误/段故障

我尝试重新编码与strstr()函数等效的方法,经过几次尝试我都正确了,这里的代码是: (我知道这样做的方法更简单,但是这次我想尝试使用第三个字符串来存储事件) 我得到了想要的输出: 但是为了确保我尝试使用更长的字符串,这就是问题开始的地方。 我尝试过的字符串 和
1回复

分割故障二叉树

我试图学习一些C语言,我首先实现了一个二叉树。 我要尝试的第一件事是插入树中。 但是,我遇到了细分错误,无法弄清原因。 当我尝试将*tree参数设置为带有传入值的新节点时,会发生分段错误。 我先尝试使用free(*tree)但这并没有帮助。 据我了解,我有一个指向我树的指针
3回复

二叉树分割故障

在这里,我编写了在二进制树中插入数字的代码。 但是它给出了分段错误错误。 并且在第8行中显示“注意:预期的'结构树*',但参数的类型为'结构节点*'”。这是代码:-
1回复

分割故障二叉树遍历

因此,我一直在运行和测试我的代码,直到我为树的预遍历和后遍历添加了2个更多函数之前,一切似乎都一直在工作。 任务是为具有随机数字集的输入文件创建链接列表和树。 链接列表和树遍历都需要在单独的函数中打印出来,而我找不到我哪里出错了。 我不断 分段故障(核心已转储) 这是我
2回复

二叉树顶视图分割故障

我正在尝试解决有关二叉树的问题,但是构建树可能会出错。 在我看来,为什么在尝试打印节点数据时出现分段错误: 输出是这样的: 我哪里出错了?
1回复

如何创建Unix进程的二叉树?

有人可以在这里帮助我,不一定完成我的作业。 我需要使用fork()创建一个进程树; 到目前为止,在Unix / C中,我能达到的最高水平是我的代码: 我对C编程非常陌生,总体而言,编程很好,所以我想问一下公众我缺少哪些步骤。 树的深度需要由用户指定,因此我认为我将使用na进行循
2回复

二叉树插入

在以下代码中,我遇到了编译错误:c2227:-> left的左边必须指向类/结构/联合/泛型类型。 任何帮助如何解决此问题; 我正在尝试插入二叉树中。
1回复

使用fork在进程的二叉树中进行广度优先搜索

我正在尝试使用c中的 fork()构建具有四个级别的进程的二进制树。 就像是: 我的目标是按顺序打印过程的每个数字(例如广度优先搜索),例如: 产量 所以我写了这段代码: 但是,当我运行代码( ./tree 4 )时,我无法控制流程的执行顺序。 我的输出有些
4回复

二叉树节点故障

这是节点定义: 我想要做的是列出所有指向祖先节点的节点。 发布错误的解决方案并从答案中获取建议后,我的新解决方案是: 递归地遍历二叉树。 将当前节点添加到节点数组中,然后检查当前节点的子节点是否指向任何先前的祖先节点。 默认情况是节点为NULL。 如果发生这种情况,函数
2回复

将文件分割成多个文件

我想根据以number(1。*)开头的行将文本文件拆分为多个文本文件,例如,我想将此文本文件拆分为2个文件: 我尝试了这个: 和这个: 但是我对如何给空行感到困惑。 (我是awk的新手。)