【问题标题】:root in binary tree always NULL二叉树中的根始终为 NULL
【发布时间】:2014-11-16 19:04:09
【问题描述】:

程序应该读取一个 txt,按字母顺序存储所有单词并按顺序打印它们,以及单词在 txt 中出现的次数。

问题似乎出在 Insert 方法中,因为它从不打印 TEST,因此 pAux 似乎出于某种原因始终为 NULL。正因为如此,Print 方法在他的第一次调用中返回。

我做错了什么?

树.h

#ifndef TREE_H_
#define TREE_H_

typedef struct Item{
    char* key;
    int no;
} TItem;

typedef struct No{
    TItem item;
    struct No* pLeft;
    struct No* pRight;
} TNo;

void TTree_Insert (TNo**, char[]);
void TTree_Print (TNo*);

#endif

树.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tree.h"

TNo* TNo_Create (char* c){
    TNo* pNo = malloc(sizeof(TNo));
    pNo->item.key = malloc(sizeof(char)*strlen(c));
    strcpy(pNo->item.key, c);
    pNo->item.no = 1;
    pNo->pLeft = NULL;
    pNo->pRight = NULL;
    return pNo;
}

void TTree_Insert (TNo** pRoot, char word[80]){
    char* c = malloc(sizeof(char)*strlen(word));
    strcpy(c, word);
    TNo** pAux;
    pAux = pRoot;
    while (*pAux != NULL){
        if (strcmp(c, (*pAux)->item.key) < 0) pAux = &((*pAux)->pLeft);
        else if (strcmp(c, (*pAux)->item.key) > 0) pAux = &((*pAux)->pRight);
        else{
            (*pAux)->item.no++;
            return;
        }
    }
    *pAux = TNo_Create(c);
    return;
}

void TTree_Print (TNo *p){
    if (p == NULL) return;
    TTree_Print (p->pLeft);
    printf("%s - %d", p->item.key, p->item.no);
    TTree_Print (p->pRight);
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "tree.h"

int main(){
    TNo* pRoot = NULL;
    FILE* txt = fopen("Loremipsum.txt", "r");
    char aux[80];
    int c, x = 0;

    while ((c = fgetc(txt)) != EOF){
        while (!(isalpha((char)c))) c = fgetc(txt);
        while (isalpha((char)c)) {
            if (isupper((char)c)) c = c+32;
            if (islower((char)c)) aux[x++] = (char)c;
            c = fgetc(txt);
        }
        aux[x] = '\0';
        TTree_Insert(&pRoot, aux);
        x = 0;
        aux[0] = '\0';
    }
    TTree_Print(pRoot);
    fclose(txt);
    return 0;
}

【问题讨论】:

  • 您永远不会更改 pRoot 的值。 TTree_Insert 只是获取 pRoot 的值。您将新节点的地址分配给 pAUx,但在函数返回时将其丢弃。
  • 如果您从 main 修改变量,则需要将该变量引用传递给函数
  • 你通过值传递pRoot

标签: c binary-search-tree


【解决方案1】:

我没有查看您的所有代码。我只会回答你的问题。您必须通过引用将 pRoot 传递给 TTree_Insert。否则,您将其副本传递给函数,并且函数内副本的任何更改都不会影响原始值。

例如

void TTree_Insert ( TNo **pRoot, char word[80] ){
    char* c = malloc(sizeof(char)*strlen(word) + 1 ); // <==
    strcpy( c, word ); // <==
    TNo* pAux;
    pAux = *pRoot;        
    //...

在 main 中你必须像这样调用函数

TTree_Insert( &pRoot, aux );

考虑到您必须调整函数的所有其他代码。例如

void TTree_Insert( TNo **pRoot, const char word[80] )
{
    char* c = malloc( sizeof( char ) * strlen( word ) + 1 );

    strcpy( c, word );

    TNo **pAux = pRoot;

    while ( *pAux != NULL )
    {
        printf("TESTE");
        if ( strcmp(c, ( *pAux )->item.key ) < 0 )
        {
            pAux = &pAux->pLeft;
        }
        else if ( strcmp(c,  ( *pAux )->item.key ) > 0 )
        {
             pAux = &pAux->pRight;
        }
        else
        { 
            ( *pAux )->item.no++;
            break;
        }
    }

    if ( *pAux == NULL ) *pAux = TNo_Create(c);

    return;
}

我希望它会起作用。:)

【讨论】:

  • 谢谢,我调整了代码以使用 ** 和 & 现在它可以工作了。 strcpy 的东西已经修复了,但我忘了提。谢谢。
  • 您显然还做了一些其他更改,因为该代码不会修改 pRoot
  • 是的,正如我所说,我根据问题中的 cmets 调整了代码以使用 **pRoot 和 Insert(&pRoot)。
  • 是吗?那是不。我说“其他”。仅凭这一点不可能解决它。
  • @ColdLucas 你可以写 TNo** pAux; pAux = pRoot; while (*pAux != NULL){ 等等。
【解决方案2】:

pRoot 最初是 NULL,以后永远不会更改它。

所以看起来 pAux 出于某种原因总是为 NULL

嗯,这就是原因...为什么不使用调试器或进行一些打印?

【讨论】:

    猜你喜欢
    • 2017-03-12
    • 1970-01-01
    • 2014-02-25
    • 2015-01-13
    • 2015-12-06
    • 2013-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多