1

リンクされたリストを印刷する方法に関する他の投稿を見たことがありますが、どれも役に立たなかったので、独自のコードを投稿することにしました。問題は次のとおりです。

名前と年齢を完全に追加することはできますが、2 番目に別の名前と年齢を追加すると、前の名前と年齢が上書きされます。

だから私が入力した場合:

Matt と 21、次に charles と 34。charles と 34 のみが出力されます。すべてを出力するにはどうすればよいですか? 助けてくれてありがとう!:)

これが私のコードです:

#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#define pause system ("pause")

// prototype variables
struct node * initnode(char*, int);
void printnode(struct node*);

struct node{
    char name[20];
    int age;
    struct node *next;
};

struct node *head = (struct node*) NULL;
struct node *end = (struct node*) NULL;

struct node* initnode(char *name, int age){
    struct node *ptr;
    ptr = (struct node*) calloc(3, sizeof(struct node));
    if(ptr == NULL) 
        return (struct node*) NULL;
    else {
        strcpy(ptr->name, name);
        ptr->age = age;
        return ptr;
    }
}

void printnode(struct node *ptr) {
    printf("Name -> %s\n", ptr->name);
    printf("Age -> %d\n", ptr->age);
}


main() {
    char name[20];
    int age, choice = 1;
    struct node *ptr;
    while(choice != 3){
        system("cls");
        printf("1. Add a name\n");
        printf("2. List nodes\n");
        printf("3. Exit");
        printf("\nEnter Menu Selection: ");
        scanf("%d", &choice);
        switch(choice) {
        case 1: printf("\nEnter a name: ");
            scanf("%s", name);
            printf("Enter age: ");
            scanf("%d", &age);
            ptr = initnode(name, age);
            break;
        case 2: if(ptr == NULL) {
                printf("Name %s not found\n", name);
            } else 
                printnode(ptr);
            pause;
            break;
        case 3: exit(3);
        default: printf("Invalid Entry");
        }// end of switch


    }// end of main

}

ああ、私は「#include」のいくつかが役に立たないかもしれないことを知っています. 私は一日中コードを追加したり削除したりしています。

4

4 に答える 4

1

リンクされたリストを作成するポインターを定義headendましたが、実際にはこれらを使用して新しい情報を保存していません。新しいノードを作成してptr変数に保存した後、実際にはリストに保存しません。

別のメソッド を追加することをお勧めしaddnodeます。これは、この新しく作成されたノードをheadおよびendポインターによって定義されたリンク リストに追加します。

void addnode(struct node *ptr) {
    if (end == NULL) {
        head = ptr;
        end = ptr;
    }
    else {
        end = end->next = ptr;
    }
}

大まかに言えば、リストに既にアイテムがあるかどうかを確認します。そうでない場合、リストの開始と終了の両方が同じノードで表されます: リスト内の唯一のノードです! それ以外の場合は、現在の末尾の後のノードを追加するノードとして、グローバルendポインターを現在の最後のノードに移動します。

これにより、複数のノード (リストのエントリ) のチェーンを維持できます。head次に、リスト全体を印刷するときは、最初のノード ( ) から最後のノードまで、このチェーン全体をたどる必要があります。単純なループでこれを行うことができます: で保持しprintnode()ている一時ptr変数を単純に呼び出す代わりにmain()、次のように記述します。

struct node *current = head;
while (current != end) {
    printnode(current);
    current = current->next;
}
于 2013-04-10T17:13:59.183 に答える
0

この行は次のとおりです。

ptr = initnode(name, age);

ptrこれが、呼び出されたローカルノードを宣言し、値を追加するたびにそのノードを次のノードで上書きするため、常に名前/年齢を上書きする理由です。

struct node *next;ノード構造にその要素が表示されますか? 次のように、複数のノードを作成するには、次のノードを作成する必要があります。

ptr->next = initnode(name, age);

リンクされたリストに関しては、最初のノードの特別なケースがあります。最初のノードptrは空です。そのため、リストの長さが 0 の場合、次にの要素を設定する必要があるときにptrfromを設定する必要があります。現在のノードになるように ptr を更新する必要があります。init_node()ptrnext

ptr = ptr->next;

もちろん、これを行うと、リストの開始を「緩める」ことになります。それがあなたの出番です。あなたが に初期化しheadた場合に開始すると、頭を動かさないでください。リストの開始位置がどこにあるかを常に覚えています。headptr

変数もあります:

struct node *end = (struct node*) NULL;

最後に追加された要素を常に指すようにするために、追加するたびにそれを更新し続ける必要があります...気になる場合。二重連結リストを作成する場合は、通常end、またはlastまたはポインタです。tail

于 2013-04-10T17:13:22.870 に答える
0

名前と年齢を完全に追加することはできますが、2 番目に別の名前と年齢を追加すると、前の名前と年齢が上書きされます。

コードは以前のノードを上書きせず、新しいノードに置き換え、以前のノードをリークします。(リークとは、割り当てたメモリの一部であり、ポインタを失ったため、割り当てを解除することはできません。) 新しいノードを作成する行は次のとおりです。

ptr = initnode(name, age);

がリストの最初のノードへのポインタである場合ptr、新しいノードを に割り当てるのではなく、リストの最後に追加する必要がありますptr

于 2013-04-10T17:49:56.150 に答える