2

ユーザーがノードを挿入し、ツリー内のすべてのノードを順番、前順、または後順モードで表示できる単純な二分探索ツリー プログラムを作成しようとしていました。私のコードは


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

struct treenode
{
int data;
struct treenode *lchild;
struct treenode *rchild;
}*root;

void insertnode(struct treenode *p,int d)
{
    if(p==NULL)
    {
         // means the tree is empty
         p=(struct treenode *)malloc(sizeof(struct treenode));
         p->data=d;
         p->lchild=NULL;
         p->rchild=NULL;
    }

    else
    {
         // start comparing the new data from root
         if( d<p->data )
             insertnode((&(p->lchild)),d);

        else
             insertnode((&(p->lchild)),d);
    }
}

void preorder(struct treenode *p)
{
    if(p==NULL)
    {
        printf("\nThe list is empty");
    }

    else
    {
        printf("%d",p->data);
        preorder(p->lchild);
        preorder(p->rchild);
    }
}

void postorder(struct treenode *p)
{
    if(p==NULL)
    {
        printf("\nThe list is empty");
    }

    else
    {
        preorder(p->lchild);
        preorder(p->rchild);
        printf("%d",p->data);
    }
}

void inorder(struct treeode *p)
{
    if(p==NULL)
    {
        printf("\nThe list is empty");
    }

    else
    {
        preorder(p->lchild);
        printf("%d",p->data);
        preorder(p->rchild);
    }
}

int main(void)
{
    root=NULL;
    int choice,data;

    while(1)
    {
         printf("\nPress 1 for inserting a node in BST fashion: ");
         printf("\nPress 2 for traversing the tree in preorder fashion :");
         printf("\nPress 3 for traversing the tree in postorder fashion :");
         printf("\nPress 4 for traversing the tree in inorder fashion :");
         printf("\nPress 5 to exit :");


         printf("\nEnter your choice: ");
         scanf("%d", &choice);

    switch(choice)
    {
        case 1: printf("\nEnter the data to be inserted:");
            scanf("%d",&data);
            insertnode(root,data);
            break;

        case 2: preorder(root);
            break;

        case 3: postorder(root);
            break;

        case 4: inorder(root);
            break;

        case 5: exit(0);
            break;

        default: printf("\nYou have enetred an invalid choice. Please try again");
    }
}

return 0;
}

というエラーメッセージがたくさんあります


dereferencing pointer to incomplete type

何が問題ですか ?また、私は二重間接ポインタにあまり慣れていないので、誰かが二重間接ポインタを渡したり取得したりする方法を説明してもらえますか (上記のプログラムでそれらを渡す必要がある場合)。

4

2 に答える 2

6

以下は単なるコンパイルエラーですので、これらを修正するとプログラムがコンパイルされます。

問題#1
構造体を次のように定義します:

struct treenode
{
    /* Blah blah... */
} *root;  /* Mistake: should be root, not *root */

代わりに、ではなく、名前を付けてrootください*root


問題#2
あなたはinsertnode()間違って呼んでいます。これの代わりに:

insertnode((&(p->lchild)),d);  /* Mistake: taking the address of the pointer */

あなたはそれをこのように呼ぶべきです:

insertnode(p->lchild,d);


問題#3
あなたは間違って定義rootしています:main()

root = NULL;  /* Mistake: root is implicitly declared as int */

代わりにすべきことは次のとおりです。

struct treenode* root = NULL;


問題#4

の宣言にタイプミスがありinorder()ます:

void inorder(struct treeode *p)  /* Typo: should be treenode and not treeode */

そのはず:

void inorder(struct treenode *p)

次の一連の問題は、プログラムの論理エラーです。

問題#5:常に新しい値を左側のノードに挿入
しています。再帰呼び出しのいずれかを次のように変更する必要があります。insertnode()dinsertnode(p->lchild, d);

insertnode(p->rchild, d);

ツリーをどのように整理するかによって異なります。


問題#6
AndersKが指摘したように、渡されたポインターrootはに渡された後も変更されないinsertnode()ため、これは大きなバグです。

あなたの場合、渡されたポインタ自体を変更したい(つまり、別のアドレスを指す)場合は、二重間接ポインタが必要であり、ポインタ自体は変更しないでください。

root内部を変更したいinsertnode()ので、別のレベルの間接参照を追加し、のアドレスを渡しますrootつまり &root、関数内でルートも変更できるようにします。

同様に、の宣言は次のようにinsertnode()なります。

insertnode(struct treenode** p, int d)
于 2012-07-16T09:02:29.543 に答える
1

ポインターが指しているデータを変更するには、もう 1 レベルの間接化を指定する必要があります。

たとえば、あなたが書く

insertnode(root,data);

ただし、ルートは開始時に NULL に設定されており、関数に指定する方法で insertnode 内で変更することはできません。

代わりに、insertnode を次のように宣言します。

insertnode(struct treenode **p,int d)

そしてinsertnodeを呼び出します

insertnode(&root, data);
于 2012-07-16T09:14:48.553 に答える