C言語

【C言語】第6章第14回:動的構造体リストの実装

動的構造体リストを使用すると、データの追加・削除が柔軟に行えます。この章では、動的構造体リストの基本から応用までを学びます。

0. 記事の概要

この記事を読むメリット

  • 柔軟なデータ管理:動的にデータを追加・削除する方法を学べます。
  • メモリ効率の向上:必要なデータのみメモリを確保し、効率的なプログラム設計が可能になります。
  • 応用力の向上:リスト構造の基礎を理解し、さらに高度なデータ構造へ応用できます。

この記事で学べること

  • 動的構造体リストの基本的な設計方法
  • リストのデータ追加・削除・表示の実装
  • 実践的なプログラム例とその解説

活用のイメージ

例えば、学生の成績管理やタスクの進捗管理システムなど、動的なデータの追加・削除が必要な場面で動的構造体リストは大いに役立ちます。

1. 動的構造体リストの基本

1.1 動的構造体リストとは?

動的構造体リストは、必要に応じてメモリを動的に確保し、リスト形式でデータを管理する方法です。リストの各要素(ノード)は、構造体で表現されます。

1.2 動的構造体リストの構造

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

// ノードを表す構造体
typedef struct Node {
    int data;
    struct Node* next;
} Node;

// 新しいノードを作成する関数
Node* createNode(int value) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = value;
    newNode->next = NULL;
    return newNode;
}
動作説明
  1. 構造体の定義:ノードを表すNode構造体を定義します。データ部分と次のノードへのポインタを持ちます。
  2. ノード作成関数:createNode関数で、新しいノードを動的に作成し、初期化します。

1.3 リストの初期化

リストを管理するためには、リストの先頭を指すポインタを初期化する必要があります。

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

// リストの初期化
int main() {
    Node* head = NULL; // リストの先頭をNULLで初期化
    return 0;
}

2. 動的構造体リストの操作

2.1 データの追加

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

// ノードを表す構造体
typedef struct Node {
    int data;
    struct Node* next;
} Node;

// 新しいノードを作成
Node* createNode(int value) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = value;
    newNode->next = NULL;
    return newNode;
}

// リストにノードを追加
void appendNode(Node** head, int value) {
    Node* newNode = createNode(value);
    if (*head == NULL) {
        *head = newNode;
    } else {
        Node* temp = *head;
        while (temp->next != NULL) {
            temp = temp->next;
        }
        temp->next = newNode;
    }
}
動作説明
  1. ノード作成:createNode関数を使い、新しいノードを作成します。
  2. リストへの追加:
    • リストが空の場合、新しいノードを先頭に設定します。
    • リストが空でない場合、末尾を見つけて新しいノードを接続します。

2.2 データの表示

#include <stdio.h>

// リストを表示
void displayList(Node* head) {
    Node* temp = head;
    while (temp != NULL) {
        printf("%d -> ", temp->data);
        temp = temp->next;
    }
    printf("NULL\n");
}
動作説明
  1. リストの走査:ポインタtempを使い、リストを先頭から末尾まで走査します。
  2. データの出力:各ノードのデータを出力し、矢印でつなげます。

2.3 データの削除

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

// リストからノードを削除
void deleteNode(Node** head, int value) {
    Node* temp = *head;
    Node* prev = NULL;

    if (temp != NULL && temp->data == value) {
        *head = temp->next;
        free(temp);
        return;
    }

    while (temp != NULL && temp->data != value) {
        prev = temp;
        temp = temp->next;
    }

    if (temp == NULL) return;

    prev->next = temp->next;
    free(temp);
}
動作説明
  1. 先頭ノードの削除:先頭ノードのデータが一致する場合、先頭を更新してノードを解放します。
  2. 中間・末尾ノードの削除:一致するデータを持つノードを探し、削除します。

3. 練習問題

以下の課題に挑戦して、動的構造体リストの理解を深めましょう。

  1. 整数データを動的構造体リストで管理し、データを昇順にソートするプログラムを作成してください。
  2. リストの全データを削除する関数を作成してください。
  3. 学生情報(名前、ID、成績)を動的構造体リストで管理するプログラムを作成してください。

4. 練習問題の解答と解説

問2の解答

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

// ノードを表す構造体
typedef struct Node {
    int data;
    struct Node* next;
} Node;

// リスト全体を削除
void deleteAll(Node** head) {
    Node* current = *head;
    Node* next;

    while (current != NULL) {
        next = current->next;
        free(current);
        current = next;
    }
    *head = NULL;
}
動作説明
  1. リストの走査:現在のノードを解放し、次のノードに進みます。
  2. リストのクリア:リストの先頭をNULLに設定し、リストを初期化します。

5. まとめ

動的構造体リストを活用すると、データの追加・削除が柔軟に行えます。次回は、さらに高度なリスト操作を学びます。