令和8年度 科目B 問4
データ構造
単方向リストに関する問題
次のプログラム中の[a]と[b]に入れる正しい答えの組合せを,解答群の中から選べ。ここで,配列の要素番号は 1 から始まる。
単方向リストを,配列 dataList と配列 pointerList の二つの配列で表現する。dataList にリストの要素の値を格納し,pointerList にリストの次の要素に対応する dataList の要素番号を格納する。単方向リストの先頭は,dataList[1] 及び pointerList[1] の組みである。単方向リストの末尾に対応する pointerList の要素は未定義である。dataList のうち単方向リストの要素の値を格納していない要素と,対応する pointerList の要素は未定義である。
プログラムが扱う dataList 及び pointerList の内容を図 1 に示す。先頭の次の要素の要素番号は,pointerList[1] に格納された 3 であり,値は dataList[3] に格納された 20 である。その次の要素の要素番号は pointerList[3] に格納された 2 であり,値は dataList[2] に格納された 30 である。
図1 dataList 及び pointerList の内容(網掛けの要素は「(網掛け)」と書いた):
| 要素番号 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| dataList | 10 | 30 | 20 | 40 | (網掛け) |
| pointerList | 3 | 4 | 2 | (網掛け) | (網掛け) |
注記 網掛けはその要素が未定義であることを示す。
関数 orderList は,図 1 の dataList 及び pointerList で表現した単方向リストの値を,単方向リストの先頭からたどって順番に格納した配列を返す。関数 orderList が返す配列を図 2 に示す。
図2 関数 orderList が返す配列:
| 要素番号 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|
| 10 | 20 | 30 | 40 |
〔プログラム〕
大域: 整数型の配列: dataList ← {10, 30, 20, 40, 未定義の値}
大域: 整数型の配列: pointerList ← {3, 4, 2, 未定義の値, 未定義の値}
○整数型の配列: orderList()
整数型: i, p ← 1
整数型の配列: linearList ← {} // 要素数0の配列
for (i を 1 から dataListの要素数 まで 1 ずつ増やす)
linearListの末尾 に dataList[p]の値 を追加する
if ([a] が 未定義)
繰返し処理を終了する
endif
p ← [b]
endfor
return linearList
解答群は原典では a・b の組合せの表。
- アa:dataList[p] / b:i
- イa:dataList[p] / b:pointerList[p]
- ウa:pointerList[p] / b:i
- エa:pointerList[p] / b:pointerList[p]
答えと解説を見る
✓ これが正解エa:pointerList[p] / b:pointerList[p]
解説
a・b とも pointerList[p] で、次の要素番号をたどります。
単方向リストは、各要素が次の要素の位置を持ち、それを順にたどって並びを表すデータ構造です。この問では値を dataList に、次の要素の要素番号を pointerList に置いており、pointerList がポインタの役割をしています。軸は、次へ進むときに何を使うかと、どの値が未定義なら末尾だと分かるかの二つです。
p は今見ている要素の要素番号で、1 から始まります。次の要素の要素番号は pointerList[p] に入っているので、p ← pointerList[p] とすればリストを一つ進められます。また、末尾の要素では対応する pointerList の要素が未定義なので、pointerList[p] が未定義かどうかを見れば、いま値を追加した要素が末尾だったと判断できます。
図 1 の値で追います。i = 1 で dataList[1] の 10 を追加し、pointerList[1] = 3 なので p = 3 です。i = 2 で 20 を追加して p = 2、i = 3 で 30 を追加して p = 4 になります。i = 4 で 40 を追加すると pointerList[4] が未定義なので繰返しを終え、{10, 20, 30, 40} が返ります。図 2 と一致するので、a・b とも pointerList[p] の組合せが正解です。
配列で表したリストでは、値の配列は中身を取り出すだけ、次へ進むのも終わりを知るのもポインタ側の配列、と役割を分けて読むと迷いません。
ほかの選択肢はなぜ違うのか
- 項番a:a には pointerList[p] が入ります。dataList[p] を調べる形では、末尾の dataList[4] に 40 が入っていて未定義ではないため止まれません。未定義の pointerList[4] を p に入れて次の回へ進み、存在しない位置の値を追加しようとしてしまいます。
- 項番b:b にも pointerList[p] が入ります。p ← i とすると、つながりを無視して要素番号の順に進むだけになります。a を正しくしても、追加される値は 10, 10, 30, 20, 40 となり、図 2 の並びにはなりません。
出典:令和8年度 基本情報技術者試験 科目B 問4
この解説に誤りを見つけたら教えてください。直して、直した記録を残します。誤りを報告する(メールが開きます)