【问题标题】:Returning error when traversing through a tree遍历树时返回错误
【发布时间】:2015-01-21 08:46:47
【问题描述】:

我试图在将每个节点添加到树时计算它们的频率,而不是插入新元素。由于某种原因,当将新键与当前树中的每个元素进行比较时,如果它们都相同,if 语句将不会返回 1。但是,该函数仍会将现有节点的频率加 1。这对我来说非常令人费解,因为我不知道为什么它会跳过 return 1,并继续在树中搜索。感谢您提前提供帮助/建议。

结构:

typedef struct node {
    char* key;
    struct node *left;
    struct node *right;
    int height;
    int frequency;
}node;

这是我的解析函数:

while(fgets(str, 100, textFile)) {

    token = strtok(str," \n");

    while (token != NULL)
    {
        key = strdup(token);
            if((sameFrequency(root, key)==1)&&root!=NULL) { 
                printf("%s", key);
                free(key);
                token = strtok (NULL, " \n");
            }
            else {
                root = insert(root, key);
                //printf("%s\n", key);
                free(key);
                token = strtok (NULL, " \n");
            }
    }
    if(ferror(textFile))
    {
        printf("you done messed up a-a-ron");
        return(0);
    }
}

检查每个节点频率的功能:

int sameFrequency(node *node, char* key) {
    if (node != NULL) {

        if(strcmp(key, node->key)==0){ //This statement is true in some cases, but will not return the 1
            node->frequency = node->frequency+1;
            printf("%d\n",node->frequency);
            return 1;
        }

        sameFrequency(node->left, key);
        sameFrequency(node->right, key);
    }
    else return 0;
}

输入看起来像这样:

wrn69 flr830 flr662 flr830 flr830 
flr231

输出(在 preOrder 中打印后):

key: wrn69, frequency: 1
key: flr830, frequency: 3
key: flr662, frequency: 1
key: flr231, frequency: 1
key: flr830, frequency: 1
key: flr830, frequency: 1

我希望它打印显示的所有内容,但我不希望将相同的密钥插入树中,只需将其频率增加 1。

TL;DR:函数跳过返回值,但仍在 if 语句中运行代码,即使在调试之后也不知道出了什么问题。

【问题讨论】:

  • 是否有更多人们希望提供的信息,这是一个不好的问题,还是肉眼难以调试?如果需要,我可以提供更多信息。

标签: c if-statement return codeblocks avl-tree


【解决方案1】:

我不确定您的代码要做什么,因为您没有定义 node 结构,但是您的函数 int sameFrequency(node *node, char* key) 有一个明显的错误:并非所有代码路径都返回一个值。为了清楚起见重新格式化一下,您可以看到如果strcmp(key, key)!=0 则返回未定义:

int sameFrequency(node *node, char* key) {
    if (node != NULL) {

        if(strcmp(key, node->key)==0){
            node->frequency = node->frequency+1;
            printf("%d\n",node->frequency);
            return 1;
        }
        else { 
            sameFrequency(node->left, key);
            sameFrequency(node->right, key);
            // Continue on out of the "if" statements without returning anything.
        }
    }
    else {
        return 0;
    }
    // NO RETURN STATEMENT HERE
}

我的编译器为此生成警告:

警告 C4715: 'sameFrequency' : 并非所有控制路径都返回值

当然你的也必须这样做,除非你故意禁用它们。此类警告很重要,应该始终在完成代码之前清除。

我猜你可能想做这样的事情?

int sameFrequency(node *node, char* key) {
    if (node != NULL) {

        if(strcmp(key, node->key)==0){
            node->frequency = node->frequency+1;
            printf("%d\n",node->frequency);
            return 1;
        }
        else { 
            int found;
            if ((found = sameFrequency(node->left, key)) != 0)
                return found;
            if ((found = sameFrequency(node->right, key)) != 0)
                return found;
            return 0;
        }
    }
    else {
        return 0;
    }
}

这会清除编译器警告。

顺便提一下,以下if 语句的顺序可能有误:

        if((sameFrequency(root, key)==1)&&root!=NULL) { 

由于 C execute left to right 中的 && 语句更有意义:

        if(root!=NULL && (sameFrequency(root, key)==1)) { 

【讨论】:

  • 感谢您的帮助!我现在要测试一下。我正在使用代码块并且没有收到此类错误。我用标志 -WALL 和 -g 编译,还有什么我应该使用的吗? P.S,包括结构
  • @BestBenchBudd - 不妨试试这里的说明:forums.codeblocks.org/index.php?topic=134.0
  • 哇,好的,我明白我做错了什么。非常感谢您,它现在可以正常工作。现在只需要弄清楚如何平衡 AVL 树!
猜你喜欢
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 2018-08-10
  • 1970-01-01
相关资源
最近更新 更多