二进制树中的根始终为NULL

时间:2014-11-16 19:04:09

标签: c binary-search-tree

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

问题似乎是在Insert方法中,因为它从不打印TEST,所以看起来pAux由于某种原因总是为NULL。因此,Print方法在第一次调用时返回。

我做错了什么?

tree.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

tree.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;
}

2 个答案:

答案 0 :(得分: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;        
    //...

在主要内容中,您必须调用类似

的功能
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;
}

我希望它能奏效。:)

答案 1 :(得分:0)

pRoot最初是NULL,您以后再也不会更改。

  

所以看起来pAux由于某种原因总是为空

嗯,这就是为什么你不使用调试器或进行打印?