1

私は新しい学習者で、リンクされたリストを作成しようとしています。私はそうすることができますが、ルートまたは最初のノードのポインターを保持しようとしているので、リンクされたリストを作成した後、リストを読み取ったり、パターン マッチングを実行したりできますが、正常に実行できません。ここで助けてもらえますか?

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

struct node {    
    int x;
    struct node *next;
};

int main(){

    int d;
    struct node *linked;
    struct node *head;

    linked = malloc (sizeof(struct node));

    head = linked;   <<<< As this is pointer, in while loop whenever malloc executes it changes the value of head as well.
    printf ("Location of head %p \n", head->next);

    d = 1;
    while (d>0){

        printf ("Enter the value of X: ");
        scanf ("%d", &linked->x);

        linked->next = malloc (sizeof(struct node));
        printf ("Location of linked %p \n", linked->next);

        printf ("Location of head %p \n", head->next);

        printf ("To enter further value enter non zero: ");
        scanf ("%d", &d);

        if (d==0)
            linked->next = NULL;
    }

    //linked->next = NULL;

    printf("Value of Next is %p\n", linked->next);        
    printf ("Location of head %p \n", head->next);        
}

出力:

MacBook-Air:cprog jimdev$ ./a.out

ヘッドの位置 0x7fff90ab952c <<<< この値は変更すべきではありませんが、ここでは後続の出力で変更します。

X: 0 の値を入力します。

リンクされた 0x7ff0624039c0 ​​の場所

先頭の位置 0x7ff0624039c0 ​​<<<< 以前とは異なる値

さらに値を入力するには、ゼロ以外を入力してください: 3

X: 3 の値を入力します。

リンクされた 0x7ff0624039d0 の場所

ヘッドの位置 0x7ff0624039d0 <<<< 以前とは異なる値

さらに値を入力するには、ゼロ以外を入力してください: 0

Next の値は 0x0 です

先頭の位置 0x0

リンクされたリスト要素のprintfも行うこの新しいものを試しました。改善点があれば教えてください。再帰がそれを達成するための迅速できちんとした方法であることは知っていますが、while ループで何かを試してみたかったのです。

含む

含む

構造体ノード {

    int x;
    struct node *next;
    };

int メイン () {

    int d, hold, i;
    struct node *list;
    struct node *head;
    struct node *current;



    list = (node *)malloc(sizeof(struct node));
    head = list;
    printf ("Location of list is %p \n", head);
    d = 1;

ながら (d>0){

    printf ("Enter the value of X: ");
    scanf ("%d", &list->x);
    printf ("Location of list is %p\n", list);
    current = (node *)malloc (sizeof (struct node));
    list->next = current;
    list = current;

    printf ("Location of head is %p\n", head);


    printf ("Enter zero to terminate the loop: ");
    scanf ("%d", &d);

    }
    list->next = NULL;
    printf ("Value of last next is %d\n", list->next);

    current = head;

    i = 1;
    while (current->next != 0){
          printf ("Location of list is %p \n", current);
          printf ("Value of linked list %d elements %d \n", i, current->x);
          current = current->next;
          i++;
          }

    scanf ("%d", &hold);

}

4

4 に答える 4

2

2つのこと:

  1. あなたはhead->nextただの代わりに出力していますhead

  2. あなたはに更新linkedしていませんlinked->next

リンク リストのヘッド ノードは、リストの最初の要素です。head->next は、リンクされたリストが整形式の場合、2 番目の要素です。いずれにせよ、リストは作成後に作成されるため、変更されるべきではありません。

に更新linkedしていない場合linked->nextは、割り当てたばかりのメモリを捨てているだけでlinked->next、リストを作成していません。

これは機能します:

int d;
struct node *linked;
struct node *head;

linked = malloc(sizeof(struct node));

head = linked;
printf ("Location of head %p \n", head);//changed head->next to head

d = 1;
while (d>0){

    printf ("Enter the value of X: ");
    scanf ("%d", &linked->x);

    linked->next = malloc (sizeof(struct node));
    printf ("Location of linked %p \n", linked->next);

    printf ("Location of head %p \n", head);// changed head->next to head

    printf ("To enter further value enter non zero: ");
    scanf ("%d", &d);

    linked = linked->next; //this was added
    if (d==0)
        linked->next = NULL;
}

あなたのコードは、更新されていないためlinked、保持されheadlinked同等です。リストは次のようになります。

ノード {x:next}

           -> {x2:NULL}
           -> {x3:NULL}
{x1:node2} -> {x4:NULL}
    ^^            ^^
(head and linked)   you're outputing this node both times  

node2 または node3 へのポインタがないため、これらのノードが失われます (メモリ リーク)。

あなたはそれをほぼ正しかった。このコードで生成されたリストは次のようになります。

{x1:node2} -> {x2:node3} -> {x3:node4} -> {x4:node5}
   ^^           ^^                           ^^
  head        head->next                   linked

アップデート:

何が起こっているかをよりよく反映するために、コードの図を変更しました。

ptr->varname演算子は、 が指す位置でのptr値を探しますvarname。したがって、ポインターが同じ値である場合は、同じスペースで変数を探しています。あなたの場合、は、 thenhead=linkedを設定し、 sinceが更新されない(したがって) 場合、割り当てと再割り当てだけであることを意味しますlinked->next = ptrhead->next = ptrlinkedlinked->nexthead->nextlinked->next

于 2013-02-08T04:40:54.183 に答える
1

リンクリストを操作する場合は、headの値を設定するだけで、変更しないでください。headの値を変更すると、すべてのリンクが「ドロップオフ」し、ガベージコレクターがそれらを使い果たします。リンクリストはこの形式に従う必要があります。

ノード番号1はヘッドであり、現在のノードに設定されます

ノード番号2は、ヘッドノード内の次のポインタに設定され、ノード2も現在のノードに設定されます

ノード3はノード2の内側の次のポインターに設定され、ノード3は現在のノードポインターに設定されます。

洗浄/すすぎ/繰り返し

ヘッドノードは絶対に変更しないでください

于 2013-02-08T04:12:18.597 に答える
1

次の段落で説明する理由から、ここでリンクリストを実際に「構築」しているわけではありません...ポインタに関する質問に関しては、ポインタと同じhead値ではない値を出力し続けます。の値を出力した場合、明示的に変更することはないため、時間の経過とともに変更されないことがわかります。head->nextheadhead

私があなたが犯しているのを見ることができる最大の間違いは、メモリを割り当ててポインタ値をに割り当てた後linked、ポイントするポインタを決して割り当てないという事実です。したがって、何が起こっているのかというと、に新しいメモリブロックを割り当て続けます。これは、と同じ値であり、によってポイントされていた以前に割り当てられたメモリブロックへの参照が失われると、メモリリークが発生します。したがって、次のようなものが必要になります。linked->nextlinked->nextlinked->nexthead->nextlinked->next

linked->next = malloc(sizeof(struct node));
linked = linked->next;

このアプローチでは、linked常にリストの最後のノードを指すループ不変条件を維持し、その結果、新しいノードをリストの最後にアタッチし、ノードへの参照を失うことはありません。headさらに、リストは変更されないため(リストの最初のノードを指しているため)、ポインターからリストをトラバースできます。

于 2013-02-08T04:16:01.063 に答える
1

これは、二重リンク リスト プログラムを書きたい初心者向けに私が書いたサンプルです。ご参考までにどうぞ。AMR によってすでに正しく指摘されているように、Head は一定のままである必要があります (リストの先頭ではなく末尾に要素を挿入していると仮定します)。

ここで head は global として実装されています。グローバル変数を持つことは必ずしも良い考えではないかもしれません。そのような場合、次のような insert_element_into_list function() にヘッドを渡します

insert_elements(head,item)

struct node {
    int d;
    node *llink;
    node *rlink;
};
typedef struct node* Node;
Node head = NULL;

void linked_list_init(int);
void linked_list_print();

void linked_list_init(int data) {

    Node newnode = (Node) malloc(sizeof (Node));
    newnode->d = data;

    Node curr;

    if (head == NULL) {

        newnode->llink = NULL;
        newnode->rlink = NULL;
        head = newnode;

    } else {
        curr = head;
        while (curr->rlink) {
            curr = curr->rlink;
        }
        curr->rlink = newnode;
        newnode->rlink = NULL;
        newnode->llink = curr;       
    }
}

void linked_list_print() {
    Node curr;
    curr = head;
    while (curr) {
        printf("Element Data : %d", curr->d);
        curr = curr->rlink;
    }
}
于 2013-02-08T04:51:24.933 に答える