問4 配列で表した単方向リストをたどる

基本情報​技術者試験 令和8年度 公開問題 科目B、全6問のうちの問4。

出典:令和8年度 基本情報技術者試験 公開問題 科目B 問4(図 1 と図 2 とプログラムは原本の画像を文字に書き起こし、字下げは 1 段を空白 2 つで表した。図 1 の網掛け (未定義) は「未定義」と書いた。空欄は[ a ][ b ]で、解答群の表は 1 行の文に組み直した)

次のプログラム中の[ a ]と[ b ]に入れる正しい答えの組合せを,解答群の中から選べ。ここで,配列の要素番号は 1 から始まる。

単方向リストを,配列 dataList と配列 pointerList の二つの配列で表現する。dataList にリストの要素の値を格納し,pointerList にリストの次の要素に対応する dataList の要素番号を格納する。単方向リストの先頭は,dataList[1] 及び pointerList[1] の組みである。単方向リストの末尾に対応する pointerList の要素は未定義である。dataList のうち単方向リストの要素の値を格納していない要素と,対応する pointerList の要素は未定義である。

プログラムが扱う dataList 及び pointerList の内容を図 1 に示す。先頭の次の要素の要素番号は,pointerList[1] に格納された 3 であり,値は dataList[3] に格納された 2⁠0 である。その次の要素の要素番号は pointerList[3] に格納された 2 であり,値は dataList[2] に格納された 3⁠0 である。

図1 dataList 及び pointerList の内容 (未定義は原本では網掛け)
要素番号12345
dataList1⁠03⁠02⁠04⁠0未定義
pointerList342未定義未定義

表は横に送ると続きが見えます。

関数 orderList は,図 1 の dataList 及び pointerList で表現した単方向リストの値を,単方向リストの先頭からたどって順番に格納した配列を返す。関数 orderList が返す配列を図 2 に示す。

図2 関数 orderList が返す配列
要素番号1234
値1⁠02⁠03⁠04⁠0
〔プログラム〕
大域: 整数型の配列: 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
  1. アa dataList[p],b i
  2. イa dataList[p],b pointerList[p]
  3. ウa pointerList[p],b i
  4. エa pointerList[p],b pointerList[p]
答えと解説を開く

正解はエです。

p は今いる要素の番号です。値 dataList[p] を足したら、次の要素へ進みます。次の要素の番号は pointerList[p] に入っているので、b は pointerList[p] です。末尾の要素では pointerList[p] が未定義なので、そこで繰返しを終えます。だから a も pointerList[p] です。追うと、p = 1 で 1⁠0 を足して p ← 3、2⁠0 を足して p ← 2、3⁠0 を足して p ← 4、4⁠0 を足したところで pointerList[4] が未定義なので終わり、{1⁠0, 2⁠0, 3⁠0, 4⁠0} になります。正解はエです。

ほかの選択肢が違う理由

  • アp ← i では、p が繰返しの回数を追うだけで、リストのつながりをたどりません。追うと、1 回目のあとも p は 1 のままで、{1⁠0, 1⁠0, 3⁠0, 2⁠0, 4⁠0} になります。
  • イ末尾の判定に dataList[p] を見ています。末尾の要素 dataList[4] は 4⁠0 で未定義ではないので、そこで止まりません。p ← pointerList[4] で p が未定義になり、次の dataList[p] が読めなくなります。
  • ウ終わりの判定は合っていますが、p ← i では回数を追うだけでリストのつながりをたどりません。追うと {1⁠0, 1⁠0, 3⁠0, 2⁠0, 4⁠0} になります。

仕組み

単方向リストは、各要素が「次の要素の場所」を持つつながりです。配列の並び順と、リストのたどる順は一致しません。

たどる処理は、値を使う、次があるか調べる、次へ進む、の 3 つの繰返しです。次の場所を指す欄 (ここでは pointerList) が、判定にも移動にも使われます。