0

C でバイナリ ツリーを作成するのに問題があります。発行年が遅い本が左側に追加され、発行年が早い本が右側に追加されるツリーに本を追加できると思います。実行エラーが発生し続けますが、その理由がよくわかりません。

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


struct book { 
    char* name; 
    int year;
};

typedef struct tnode { 
    struct book *aBook; 
    struct tnode *left; 
    struct tnode *right;
} BTree;

BTree* addBook(BTree* nodeP, char* name, int year){
    if( nodeP == NULL )
    {
        nodeP = (struct tnode*) malloc( sizeof( struct tnode ) );
        (nodeP->aBook)->year = year;
        (nodeP->aBook)->name = name;
        /* initialize the children to null */
        (nodeP)->left = NULL;    
        (nodeP)->right = NULL;  
    }
    else if(year > (nodeP->aBook)->year)
    {
        addBook(&(nodeP)->left,name,year );
    }
    else if(year < (nodeP->aBook)->year)
    {
        addBook(&(nodeP)->right,name,year );
    }
    return nodeP;
}

void freeBTree(BTree* books)
{
    if( books != NULL )
    {
        freeBTree(books->left);
        freeBTree(books->right);
        //free( books );
    }
}

void printBooks(BTree* books){
    if(books != NULL){

    }
}

int main(int argc, char** argv) {
    BTree *head;
    head = addBook(head,"The C Programming Language", 1990);
    /*addBook(head,"JavaScript, The Good Parts",2008);
    addBook(head,"Accelerated C++: Practical Programming by Example", 2000);
    addBook(head,"Scala for the impatient",2012);*/
}
4

2 に答える 2

2

初期化されていないポインタにアクセスしようとしていますnodeP->aBook:

nodeP = (struct tnode*) malloc( sizeof( struct tnode ) );
(nodeP->aBook)->year = year;
  • でスペースを割り当てる必要がありmallocます。
  • または、データをノードに直接格納します (構造体へのポインターではなく、構造体を使用)。
于 2012-09-24T23:56:48.763 に答える
1

1 つの問題は、NULL に初期化していないことです。

BTree *head;

する必要があります

BTree *head = NULL;

コンパイラの警告を高く設定することをお勧めします。あなたの 2 つの再帰呼び出しは正しくないため、コンパイラはそれらについて警告する必要があります。

addBook(&(nodeP)->left,name,year );

次のようにする必要があります。

addBook( nodeP->left,name,year );

パラメータ受け渡しの観点から。ただし、この関数は、ノード ポインターが NULL のときに追加しているため、現時点では機能しません。つまり、親ポインター ノードがなくなっているため、親を子にアタッチすることはできません。ロジックは該当する右/左ノードを調べ、NULL の場合はルーチンに追加し、それ以外の場合は NULL 右/左ポインターを持つノードが見つかるまで再帰的に呼び出す必要があると思います。

このようなもの:

BTree *makeNode(char *name, int year)
{
   // NOTE: 3 frees required for every node
   BTree *nodeP = malloc( sizeof( struct tnode ) );  // 1
   nodeP->aBook = malloc( sizeof(struct book) );     // 2
   (nodeP->aBook)->year = year;
   (nodeP->aBook)->name = malloc(strlen(name) + 1);  // 3
   strcpy((nodeP->aBook)->name,name);
   /* initialize the children to null */
   nodeP->left = NULL;    
   nodeP->right = NULL;  
   return nodeP;
}

BTree* addBook(BTree* nodeP, char* name, int year)
{
    if ( nodeP == NULL )
    {
        nodeP = makeNode(name,year);
    }
    else if (year > (nodeP->aBook)->year)
    {
       if ( nodeP->left == NULL )
          nodeP->left = makeNode(name,year);
       else
          addBook( nodeP->left,name,year );
    }
    else if(year < (nodeP->aBook)->year)
    {
       if ( nodeP->right == NULL )
          nodeP->right = makeNode(name,year);
       else
          addBook( nodeP->right,name,year );
    }
    return nodeP;
}

void printBooks(BTree* books) 
{
    if (books != NULL) {
       printf("book: %s %d\n",books->aBook->name,books->aBook->year);
       printBooks(books->right);
       printBooks(books->left);
    }
}
于 2012-09-24T23:57:12.097 に答える