C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で不変リンクリストを逆順に出力する方法

問題の概要

不変(イミュータブル)なリンクリストが与えられたとき、各ノードの値を逆順にすべて出力することを考えます。この問題を解くためには、以下のインターフェースを使用します。

  • ImmutableListNode ― 不変リンクリストのインターフェースであり、リストの先頭ノード(head)が与えられます。

リンクリストへアクセスするために、次の2つの関数が利用できます。

  • ImmutableListNode.printValue() ― 現在のノードの値を出力します。
  • ImmutableListNode.getNext() ― 次のノードを返します。

たとえば、リストが [0, -4, -1, 3, -5] の場合、出力は [-5, 3, -1, -4, 0] となります。

解法のアプローチ

リンクリストは不変(イミュータブル)であるため、ノードのポインタを書き換えて逆順にすることはできません。そこで、スタックのLIFO(後入れ先出し)の性質を利用します。ノードを順番にスタックへ格納し、その後スタックから取り出しながら値を出力すれば、自然と逆順になります。

アルゴリズムの手順

  • ImmutableListNode 型のノードを格納するスタック st を定義します。
  • head が null でない間、以下を繰り返します。
    • head をスタック st にプッシュします。
    • head を次のノード(getNext() の結果)に更新します。
  • スタックが空でない間、以下を繰り返します。
    • スタックの先頭ノードの値を出力します。
    • スタックからノードを取り除きます(ポップ)。

C++での実装例

以下の実装を見ると、理解がより深まるでしょう。

class Solution {
public:
    void printLinkedListInReverse(ImmutableListNode* head) {
        stack <ImmutableListNode*> st;
        while(head){
            st.push(head);
            head = head->getNext();
        }
        while(!st.empty()){
            st.top()->printValue();
            st.pop();
        }
    }
};

入力例

[0,-4,-1,3,-5]

出力例

[-5,3,-1,-4,0]

計算量の分析

  • 時間計算量: O(n) ― 各ノードを1回ずつスタックにプッシュし、1回ずつポップするため、リストの長さ n に対して線形時間で処理が完了します。
  • 空間計算量: O(n) ― すべてのノードを一時的にスタックに保持するため、追加のメモリが必要です。

なお、再帰を用いて同様の結果を得ることも可能ですが、リストが長い場合にはスタックオーバーフローのリスクがあるため、明示的なスタックを使うこの方法が安全です。

  1. C++で連結リストの交互ノードの合計を求める方法(反復法・再帰法)

    問題概要 この記事では、連結リスト(リンクリスト)が与えられたときに、その交互ノード(0、2、4…番目のノード)の値の合計を求める方法を解説します。 連結リストとは、リンク(ポインタ)によって順次接続されたデータ構造の列です。各ノードはデータ本体と、次のノードを指す参照を持っています。 今回の課題は、連結リストのうち位置 0、2、4、6 … にあるノード、つまり先頭から1つおきのノードの値をすべて加算することです。 入出力例 入力: 4 → 12 → 10 → 76 → 9 → 26 → 1 出力: 24 説明: 交互ノードを取り出すと − 4 + 10 + 9 + 1 = 24 解決の考

  2. 【C++】再帰を使ってリンクリストの交互ノードを出力する方法

    リンクリスト(連結リスト)とはリンクリストは、各要素(ノード)をメモリ上の連続しない領域に格納できる線形データ構造です。各ノードにはデータ本体と、次のノードを指すポインタが含まれており、ポインタをつなぐことで一連のリストとして扱うことができます。問題の概要今回は、与えられたリンクリストを走査し、交互(ひとつおき)のノードだけを出力するプログラムを作成します。具体的には、1番目・3番目・5番目…というように、奇数番目の要素のみを順に出力していきます。入出力例入力 : 2 -> 4 -> 1 -> 67 -> 48 -> 90 出力 : 2 -> 1 ->