連結リストのノード構造体定義
C言語における単方向リストの各要素は、データを保持するフィールドと、次の要素へのメモリアドレスを持つ構造体として定義されます。
typedef struct ListItem {
int value;
struct ListItem* link;
} ListItem;
リスト先頭へのノード挿入ロジック
リストを新規作成する際、最初は要素が存在しないため、先頭ポインタはNULLを指します。
ListItem* start = NULL;
新しいノードをリストの先頭に追加するには、ヒープ領域にメモリを割り当て、データを設定した後、その新しいノードをリストの新しい先頭として繋ぎ替えます。ここでは、呼び出し元で先頭ポインタを直接更新できるよう、ポインタへのポインタ(ダブルポインタ)を引数に取る設計を採用します。
void addFront(ListItem** startRef, int val) {
ListItem* freshNode = (ListItem*)malloc(sizeof(ListItem));
freshNode->value = val;
freshNode->link = *startRef;
*startRef = freshNode;
}
リストが空の状態では、*startRefはNULLです。freshNode->linkにNULLが代入され、*startRefがfreshNodeを指すようになります。これにより、最初のノードが正しく設定されます。
既存のノードが存在する場合は、freshNode->linkが現在の先頭ノードを指すように設定され、その後*startRefがfreshNodeのアドレスに更新されます。結果として、新しいノードがリストの先頭に配置されます。
実装の全体像
先頭への挿入処理に加え、リストの全要素を順番に出力する関数displayListを実装し、動作確認を行えるようにした完全なコードは以下の通りです。
#include <stdio.h>
#include <stdlib.h>
typedef struct ListItem {
int value;
struct ListItem* link;
} ListItem;
void addFront(ListItem** startRef, int val) {
ListItem* freshNode = (ListItem*)malloc(sizeof(ListItem));
freshNode->value = val;
freshNode->link = *startRef;
*startRef = freshNode;
}
void displayList(ListItem* current) {
printf("List: ");
while (current != NULL) {
printf("%d ", current->value);
current = current->link;
}
printf("\n");
}
int main() {
ListItem* start = NULL;
int count, i, val;
printf("How many elements to add?\n");
scanf("%d", &count);
for (i = 0; i < count; i++) {
printf("Enter value: \n");
scanf("%d", &val);
addFront(&start, val);
displayList(start);
}
return 0;
}