2022年4月25日公開分 [科目B]問3

お塩さん  
(No.1)
タイトルの問題について質問です。
いろいろなサイトで同じ問題の解説をよみましたがイマイチBがcurrとなる理由が分かりません。

currに値pValを入れる
?
最初のif文で最初のデータであればcurrをListHeadに設定
?
その後入ってきた値についてはelseでまずはListHeadに
?
リストの最後に追加するため繰り返し処理で最後まで移動
?
最後に追加されたリストの次の値は先頭を設定して輪っかのようにしなければならないからBを設定する


ということだと今の所理解しています。
であればBは『prev.next←ListHead』では無いのでしょうか?elseに入った時点でcurrはListHeadには設定され無いのですから先頭を探したいのであればListHeadしか無いように思えます。

どなたか解説お願いいたしますm(_ _)m
2023.09.24 15:38
電タックさん 
(No.2)
途中までの理解までがほぼ完璧なのですごく惜しいです。

作ろうとしているものが「単方向リスト」のため最後(未定義)があります。

要素のイメージとしては次の感じにたすき掛けのように並びます。
val  「東京」「名古屋」「大阪」
next 「名古屋」「大阪」「未定義」

これに京都を追加処理を行うと
>currに値pValを入れる
で下のListElementが作られます。
「京都」
「未定義」

これを今の所最後の要素の「大阪」のnextにくっつける感じで
val  「東京」「名古屋」「大阪」「京都」
next 「名古屋」「大阪」「京都」「未定義」
こうなります。

>先頭を設定して輪っかのよう
ちなみにこれは「循環リスト」という名前で一応存在しています。
また
今回の「単方向リスト」から、前の要素に戻れるリストを「双方向リスト」といいます。
2023.09.24 17:31
カニサさん 
(No.3)
基本情報技術者試験 科目 B のサンプル問題
問3
「手続 append は・・・」の問題でしょうか?
大変恐縮ですが投稿させていただきます

■まず自分で例となる単方向リストを作成します
[1]Val:A・next:2  →  [2]val:B・next:3  →  [3]val:C・next:未定義
([]の中の数字は単方向リストの要素番号、valは値、nextは次の値が入っている要素番号の位置を指します)

■問題文より「ListHeadは先頭要素を指す」より
変数ListHead→[1]Val:A・next:2  →  [2]val:B・next:3  →  [3]val:C・next:未定義
というものが出来上がります

■プログラムに入ります、手続きappendで、例えば引数qValを  [4]val:D/next:未定義  として、単方向リストに追加したいとします
([4]val:D/next:未定義  の形は図にあるコンストラクタより作りました)

■プログラム
「変数宣言  prev,curr」
「curr ← ListElement(qVal)」
より
curr→[4]val:D/next:未定義
=currは新たに作った[4]を参照します

■if文  空欄a
現在の状態ではheadは未定義では有りません、[1]を指しています。
もし単方向リストが未定義であれば(空っぽであれば)、手続きappendで  
単方向リストに[4]val:D/next:未定義  を追加してやれば終わりです。
ListHeadが、現在currが参照している  curr→[4]val:D/next:未定義  を参照して終わりです。(ListHead→[4]val:D/next:未定義)
よって空欄aは未定義が入ります

■現在の状態ではheadは未定義では有りませんのでelseへ行きます
「prev ← ListHead  」より
変数prevもListHeadが参照している  [1]Val:A・next:2  を指します。
Head/prev  →  [1]Val:A・next:2  →  [2]val:B・next:3  →  [3]val:C・next:未定義
となります

■while文へ入ります
「prev ← prev.next」より
prevが現在参照している[1]のnext(prev.next)を指します
そうするとこうなります  prev  →  [2]val:B・next:3
[2]のnextは未定義ではないのでwhile文の「prev ← prev.next」を繰り返します
そうするとこうなります
  prev  →  [3]val:C・next:未定義
ここでwhile文を抜ける条件のprev.next が未定義となりましたのでendwhileへ

■ここで各変数の現在の状態(参照先)を整理すると
Head  →  [1]Val:A・next:2
curr  →  [4]val:D/next:未定義
prev  →  [3]val:C・next:未定義

■空欄b
prev.next の後にqValを追加してあげると
[1]Val:A・next:2  →  [2]val:B・next:3  →  [3]val:C・next:4  →  [4]val:D/next:未
手続きappendの目的が果たせるので(この並びにしたいので)
prev.nextに  currが参照している  [4]val:D/next:未定義  をつなげる
prev.next  →  curr
となります

■ポイント
・オブジェクト指向の代入マークの「←」は矢印の向きを逆にして解釈する
  EX.  prev ← listHead  =  prevがListHeadを指す

・ドットマーク「.」は「の」と読む
  EX.「prev.next」  =  prevのnext

長くなってしまいましたが
こんな感じの回答でいかがでしょうか?
2023.09.25 17:12

返信投稿用フォーム

スパム防止のためにスレッド作成日から30日経過したスレッドへの書込みはできません。

その他のスレッド


Pagetop