データ構造:シーケンシャルリスト(順次リスト)のコード

📢 この記事は gemini-3-flash-preview によって翻訳されました

コード

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <stdio.h>
#include <stdlib.h> // malloc()、exit()

#define Size 5  // Sizeをマクロ定義。シーケンシャルリストの初期メモリサイズを表すよ

typedef struct Table
{
    int * head; // headという名前の、長さが決まっていない配列(動的配列)を宣言するよ
    int length; // 現在のシーケンシャルリストの長さを記録するよ
    int size;   // シーケンシャルリストに割り当てられたストレージ容量を記録するよ
}table;

// 初期化関数
table initTable()
{
    table t;

    t.head = (int*)malloc(Size * sizeof(int));  // 空のシーケンシャルリストを作成して、メモリを動的に確保するよ

    if (!t.head)    // もしメモリの確保に失敗したら、メッセージを出してプログラムを終了するよ
    {
        printf("初期化に失敗したよ");
        exit(0);
    }

    t.length = 0;   // 空のリストの長さを0で初期化
    t.size = Size;  // 空のリストの初期容量をSizeにするよ

    return t;
}

// 挿入関数。elemは挿入する要素、addは挿入する場所だよ
table addTable(table t, int elem, int add)
{
    int i;

    // 挿入位置が正しいかチェックするよ(リストの長さ+1より大きいか、1より小さい場合はエラー)
    if (add > t.length + 1 || add < 1) 
    {
        printf("挿入位置に問題があるよ");
        return t;
    }
    // 挿入する前に、空き容量があるか確認。足りなければメモリを再確保するよ
    if (t.length == t.size) 
    {
        t.head = (int *)realloc(t.head, (t.size + 1) * sizeof(int));
        if (!t.head) 
        {
            printf("メモリの再割り当てに失敗したよ");
            return t;
        }
        t.size += 1;
    }
    // 挿入位置以降の要素を、一つずつ後ろにずらすよ
    for (i = t.length - 1; i >= add - 1; i--) 
    {
        t.head[i + 1] = t.head[i];
    }

    // ずらし終わったら、指定の位置に要素を入れるよ
    t.head[add - 1] = elem;
    // 要素が増えたから、長さを+1するよ
    t.length++;
    
    return t;
}

// 削除関数
table delTable(table t, int add) 
{
    int i;

    if (add > t.length || add < 1) 
    {
        printf("削除する要素の位置がおかしいよ");
        exit(0);
    }
    for (i = add; i < t.length; i++) 
    {
        t.head[i - 1] = t.head[i];
    }

    t.length--;

    return t;
}

// 検索関数。elemは探したいデータの値だよ
int selectTable(table t, int elem) 
{
    int i;
    
    for (i = 0; i < t.length; i++) 
    {
        if (t.head[i] == elem) 
        {
            return i + 1;
        }
    }

    return -1;
}

// 更新関数。elemを新しい要素newElemに書き換えるよ
table amendTable(table t, int elem, int newElem) 
{
    int add = selectTable(t, elem);

    t.head[add - 1] = newElem;

    return t;
}

// リストの中身を表示する関数
void displayTable(table t) 
{
    int i;

    for (i = 0; i < t.length; i++) 
    {
        printf("%d ", t.head[i]);
    }
    printf("\n");
}

int main() {
    int i, add;

    table t1 = initTable();

    // シーケンシャルリストに要素を追加していくよ
    for (i = 1; i <= Size; i++) 
    {
        t1.head[i - 1] = i;
        t1.length++;
    }

    printf("元のシーケンシャルリスト:\n");
    displayTable(t1);

    printf("要素1を削除:\n");
    t1 = delTable(t1, 1);
    displayTable(t1);

    printf("2番目の位置に要素5を挿入:\n");
    t1 = addTable(t1, 5, 2);
    displayTable(t1);

    printf("要素3の位置を検索:\n");
    add = selectTable(t1, 3);
    printf("%d\n", add);
    
    printf("要素3を6に変更:\n");
    t1 = amendTable(t1, 3, 6);
    displayTable(t1);

    return 0;
}

実行結果

プログラムを実行すると、こんな感じになるよ:

元のシーケンシャルリスト:
1 2 3 4 5
要素 1 を削除:
2 3 4 5
2 番目の位置に要素 5 を挿入:
2 5 3 4 5
要素 3 の位置を検索:
3
要素 3 を 6 に変更:
2 5 6 4 5

Visits Since 2025-02-28

Hugo で構築されています。 | テーマ StackJimmy によって設計されています。