0

昨日、私はリンクされたリストを実装しようとしていました.

ここで関数 addNode() の何が問題になっていますか?

#include <stdio.h>

struct Node
{
    int value;
    struct Node *next;
};

struct Node *createList();
void addNode(struct Node* head, int value); // Adds Node directly after head
void viewList(struct Node *head); // Outputs list starting from head

int main()
{
    struct Node *head = createList();

    addNode(head, 10);
    addNode(head, 8);
    addNode(head, 23);
    addNode(head, 5);
    addNode(head, 4);
    addNode(head, 4100);


    viewList(head); // I didn't upload here to save space

    return 0;
}

struct Node *createList()
{ 
    struct Node *head = (struct Node *) malloc(sizeof(struct Node));
    head = NULL;
    return head;
}

void addNode(struct Node* head, int value)
{
    if(head == NULL)
    {
        struct Node *tmp = (struct Node *) malloc(sizeof(struct Node));
        tmp->value = value;
        tmp->next = head;
        head = tmp;
    }

    else
    {
        struct Node *newNode = (struct Node *) malloc(sizeof(struct Node));
        newNode->value = value;
        newNode->next = head;
        head = newNode;
    }
}

私が混乱している理由は、このバージョンの追加ノードが機能していたのに、そのバージョンが機能しなかったためです...

void addNode(struct Node** head, int value)
{
    if(*head == NULL)
    {
        struct Node *tmp = (struct Node *) malloc(sizeof(struct Node));
        tmp->value = value;
        tmp->next = *head;
        *head = tmp;
    }

    else
    {
        struct Node *newNode = (struct Node *) malloc(sizeof(struct Node));
        newNode->value = value;
        newNode->next = *head;
        *head = newNode;
    }
}

そしてそれは、ヘッド ノード ポインタの前にアンパランドを使用してメイン関数で呼び出されました

addNode(&head, 10);

私も当惑するのはこれです。パラメータリストと関数内でポインタを受け取り、ポインタが指しているものを変更するいくつかの練習用関数を書きました。この **pointer 構文を使用する必要はありませんでした。

4

4 に答える 4

0

ここがうまくいかない

struct Node *createList()
{ 
    struct Node *head = (struct Node *) malloc(sizeof(struct Node));
    head = NULL;
    return head;
}

ノードを割り当ててヘッドがそれを指すようにした後、ヘッドを NULL を指すように設定します。

于 2013-03-16T16:07:39.070 に答える
0

これは、パラメーターが値で渡されることに関係しています。したがって、最初の非動作バージョンでは、へのポインターがhead値によって渡されるため、変数は関数内のローカル変数になります。関数が戻るとき、ローカル変数への変更は関数の外では見えません。

ただし、2 番目のバージョンでは参照によってポインターを渡すため、関数は実際のポインターがメモリ内のどこにあるかを認識し、そのメモリに直接格納できます。


ASCII ダイアグラム時間:

次の 3 つの変数があるとします。

int value1;
int *pointer1 = &value1;
int **pointer2 = &pointer1;

変数のメモリは次のようになります。

+---------+ +----------+ +--------+
| | ポインタ 2 | --> | ポインター1 | --> | 値1 |
+---------+ +----------+ +--------+

だからpointer2を指しpointer1、そして をpointer1指しvalue1ます。

逆参照演算子*onを使用するpointer2と、何pointer2を指すかの値、つまりが取得されますpointer1

于 2013-03-16T14:24:57.433 に答える
0

文体(同じことを繰り返さないでください)::

void addNode(struct Node** head, int value)
{
    if(*head == NULL)
    {
        struct Node *tmp = (struct Node *) malloc(sizeof(struct Node));
        tmp->value = value;
        tmp->next = *head;
        *head = tmp;
    }

    else
    {
        struct Node *newNode = (struct Node *) malloc(sizeof(struct Node));
        newNode->value = value;
        newNode->next = *head;
        *head = newNode;
    }
}

if/else :: は必要ありません

#include <stdlib.h>

void addNode(struct Node **head, int value)
{

        struct Node *newNode = malloc(sizeof *newNode);
        if ( !newNode) { error(); return;}
        newNode->value = value;
        newNode->next = *head; // Could be NULL, but we need a NULL anyway in that case
        *head = newNode;

}
于 2013-03-16T14:45:04.047 に答える
0

ここにあります:

バグがありますcreateList

struct Node *createList()
{
    struct Node *head = malloc(sizeof(*head));
    head->value = 0;   //< Probably you want this
    head->next = NULL; //< You definitively wanted this
    return head;
}

リストの末尾にノードを追加する場合は、次のaddNodeようになります。

void addNodeLast(struct Node* head, int value)
{
    struct Node *tailNode;
    struct Node *newNode;

    newNode = malloc(sizeof(*newNode));
    newNode->value = value;
    newNode->next = NULL;

    // Find the last node in the list
    for (tailNode = head; tailNode->next; tailNode = tailNode->next); 

    tailNode->next = head->next;
}

ヘッドの後にノードを挿入する場合:

void addNodeAfterHead(struct Node* head, int value)
{
    struct Node *newNode;

    newNode = malloc(sizeof(*newNode));
    newNode->value = value;
    newNode->next = head-next;

    head->next = newNode;
}

ヘッドを変更する場合 (毎回新しいヘッドを作成する):

Node *addNodeNewHead(struct Node* head, int value)
{
    struct Node *newNode;

    newNode = malloc(sizeof(*newNode));
    newNode->value = value;
    newNode->next = head;

    return newNode;
}

...
Node * head = createList();
head = addNodNewHead(head, 3);
head = addNodNewHead(head, 5);
于 2013-03-16T16:28:30.133 に答える