1

私はまだリンクされたリストを学んでおり、リンクされたリストに挿入する方法を作成しようとしています。

これが正しい挿入方法かどうか知りたいだけですか?また、リンクされたリスト全体を印刷するにはどうすればよいので、次のように印刷しますabc

ここに私が持っているものがあります:

struct node {
   char value;
   struct node *next;
};

typedef struct node item;

void main() {
    InsertChar('a');
    InsertChar('b');
    InsertChar('c');
}

void InsertChar(char s) {
    item *curr, *head;

    head = NULL;

    curr = (item *)malloc(sizeof(item));
    curr->value = s;
    curr->next = head;
    head = curr;

    while(curr) {
        printf("%c\n", curr->value);
        curr = curr->next;
    }
}
4

2 に答える 2

3

まず、関数InsertCharhead毎回の値を上書きしているため ( head = curr)、1 つの項目のリストになってしまいます。

を格納するものを宣言する必要がありますhead

struct list
{
    struct node *head;
};

listこれで、それぞれを実行することで簡単に印刷できますnode

void PrintList(struct list* list)
{
    struct node *curr = list->head;

    while (curr != NULL)
    {
        printf("%c\n", curr->value);
        curr = curr->next;
    }
}

InsertCharここで、リストの最後の項目 (どうやって見つけますか?) が新しい項目を指すように変更する必要があります。私はそれをあなたに任せます:)

于 2013-11-03T04:48:12.660 に答える
0

お気づきかもしれませんが、外部からリスト (存在する場合) にアクセスする手段はありませんInsertChar()。グローバル変数を使用したり、入力または出力したりしません。

より良い実装:

item * InsertChar(item ** phead, char s) {
    item * curr;

    // First, allocate a new item and fill it.
    curr = malloc(sizeof(item)); // no need to cast here
    if (curr) { // only if malloc() succeeds
        curr->value = s;
        curr->next = *phead;
        *phead = curr;
    }
    return curr;
}

// InsertChar() is only supposed to insert, not to print.
void PrintList(item * head) {
    item * curr = head;   
    while(curr) {
        printf("%c", curr->value); // omit the line break as you want abc
        curr = curr->next;
    }
    printf("\n"); // now the line break
    return;
    // alternative implementation for while loop:
    for(curr=head; curr; curr=curr->next) {
        printf("%c\n", curr->value);
    }
}

void FreeList(item * head) {
    item * curr = head;   
    while(curr) {
        item * next = curr->next; // read it out before freeing.
        free(curr);
        curr = next;
    }
}

今できるように

int main() {
    item * list = NULL; // empty for now, no contents.
    char success = 1;
    success = success && InsertChar(&list, 'a');
    success = success && InsertChar(&list, 'b');
    success = success && InsertChar(&list, 'c');
    if (!success) {
        printf("Oops?");
        FreeList(list);
        return 1;
    }
    PrintList(list);
    FreeList(list); // clean up.
}

おっとっと?私はそれをテストしませんでしたが、「cba」と出力されるようです。なぜそうなるのですか?そうです、InsertChar() はすべてを開始します。

これを回避するにはどうすればよいですか?

AppendChar() 関数を作成することもできます。しかし、これは画家シュレミエルのアルゴリズムの罠に陥る危険をはらんでいます。したがって、別のアプローチを指摘します。

int main() {
    item * list = NULL; // empty for now, no contents.
    item * cursor = InsertChar(&list, 'a');
    if (!cursor) goto error;
    // cursor now contains our first entry.
    // We put the next one to cursor->next:
    cursor = InsertChar(&cursor->next, 'b');
    if (!cursor) goto error;
    cursor = InsertChar(&cursor->next, 'c');
    if (!cursor) goto error;
    PrintList(list);
    FreeList(list); // clean up.
    return 0;
  error:
    printf("Oops?");
    FreeList(list);
    return 1;
}

私が正しいかどうかはわかりませんが(テストしていません)、これが進むべき道です。

あなたが goto はどんな状況でも悪いと教えられたこれらの 1 人である場合は、別の方法でエラー処理を自由に実装してください。

于 2013-11-03T18:36:03.320 に答える