繁体   English   中英

二叉树的分段错误

[英]Segmentation fault on binary tree

我正在开发一个程序,该程序搜索程序并输出它遇到大于或等于函数参数中指定的值的数字的次数。 我在下面附上了我的代码,我看到它在发生分段错误之前遍历了两个值。 分段错误错误指向return count + count_values(value, here) + count_values(value, current);

typedef struct BinaryTree {
    int val;
    struct BinaryTree *left;
    struct BinaryTree *right;
} BinaryTree;

BinaryTree *build_tree(int value, BinaryTree *leftnode, BinaryTree *rightnode) {
    BinaryTree *out = calloc(1, sizeof(BinaryTree));
    out->val = value;
    out->leftnode = leftnode;
    out->rightnode = rightnode;

    return out;
}

int count_values(int value, BinaryTree *tree) {
  
    BinaryTree *current = tree;
    BinaryTree *here = current;
    int count = 0;

    if (current != NULL) {
        printf("Value in tree is not NULL\n");

        if (current->val < value) {
            printf("%d < %d\n", current->val, value);
            printf("Count value: %d\n", count);
            here = current->leftnode;
            count_values(value, here);
            current = current->rightnode;
            count_values(value, current);

        } else if (current->val == value) {
            printf("%d = %d\n", current->val, value);
            count++;
            printf("Count value: %d\n", count);
            here = current->leftnode;
            count_values(value, here);
            current = current->rightnode;
            count_values(value, current);
        } else {
            printf("%d > %d\n", current->val, value);
            count++;
            printf("Count value: %d\n", count);
            here = current->leftnode;
            count_values(value, here);
            current = current->rightnode;
            count_values(value, current);
        }
    }
        
    return count + count_values(value, here) + count_values(value, current);
}

int main(void) {
    BinaryTree *tree =
        build_tree(14, build_tree(3, NULL, NULL),
                   build_tree(15, NULL, build_tree(42, NULL, NULL)));

    //path is 14->15->42
    int count = count_values(42, tree);
    printf("should have a count of 1, got %d\n", count);

    count = count_values(14, tree);
    printf("should have a count of 3, got %d\n", count);

    return 0;
}

对于初学者来说,这两个功能都有拼写错误,例如

out->leftnode = leftnode;
out->rightnode = rightnode;

here = current->leftnode;
current = current->rightnode;

你必须写

out->left = leftnode;
out->right = rightnode;

here = current->left;
current = current->right;

在函数count_values已经有这个 if 语句

if (current->val != NULL) {

调用未定义的行为。

首先,它没有任何意义。 其次,在访问节点的数据成员之前,您需要检查指针current (更准确地说是指针tree )是否为空指针。

注意像这样的陈述

count_values(value, here);
count_values(value, current);

实际上没有任何效果。

递归函数可以通过以下方式定义

size_t count_values( const BinaryTree *tree, int value ) 
{
    return tree == NULL 
        ? 0 
        : ( tree->val >= value ) + count_values( tree->left, value ) + count_values( tree->right, value );
}    

指向树的指针应该是第一个函数参数并使用限定符const声明,因为该函数不会更改树。 并且该函数应该返回一个无符号整数类型的对象,因为计数器不能是负值。 您可以使用例如unsigned int类型而不是返回类型size_t

这是一个演示程序。

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

typedef struct BinaryTree {
    int val;
    struct BinaryTree *left;
    struct BinaryTree *right;
} BinaryTree;

BinaryTree *build_tree(int value, BinaryTree *leftnode, BinaryTree *rightnode) {
    BinaryTree *out = calloc(1, sizeof(BinaryTree));
    out->val = value;
    out->left = leftnode;
    out->right = rightnode;

    return out;
}

size_t count_values( const BinaryTree *tree, int value ) 
{
    return tree == NULL 
        ? 0 
        : ( tree->val >= value ) + count_values( tree->left, value ) + count_values( tree->right, value );
} 

int main(void) {
    BinaryTree *tree =
        build_tree(14, build_tree(3, NULL, NULL),
                   build_tree(15, NULL, build_tree(42, NULL, NULL)));

    //path is 14->15->42
    size_t count = count_values( tree, 42);
    printf("should have a count of 1, got %zu\n", count);

    count = count_values(tree, 14 );
    printf("should have a count of 3, got %zu\n", count);

    return 0;
}

它的输出是

should have a count of 1, got 1
should have a count of 3, got 3

你让这种方式变得比它需要的更难。

首先通过测试tree是否为NULL来测试基本情况。

如果不是,则在左右节点上递归,并将这些计数添加到当前节点的计数中。

int count_values(int value, BinaryTree *tree) {
    if (tree == NULL) {
        return 0;
    }

    int count = tree->val >= value;
    count += count_values(value, tree->left);
    count += count_values(value, tree->right);

    return count;
}
  1. if (current->val != NULL) { current->value 永远不能是 NULL 指针,因为值不是指针。 它只是整数。 您可能应该检查current而不是current->val
  2. 即使您更正了该行,您的程序也会出现段错误导致堆栈溢出(呵呵),因为您在return count + count_values(value, here) + count_values(value, current); 线

PS您发布的代码需要一些调整才能构建。 可以的话修一下

暂无
暂无

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

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