このスレッドでは、かなりの混乱と誤解があります。実際には、隣接行列(および任意の配列一般)の初期化コストを回避する方法があります。ただし、Javaプリミティブでのメソッドの使用はデフォルトでは初期化されているため使用できません。
アレイdata[0..n]
が自動初期化されていないとすると、始めるには、それは前に記憶にあったものから迷惑でいっぱいです。 O(n)時間を上書きしたくない場合は、迷惑データから追加した良好なデータを区別するための方法が必要です。
"トリック"は、良好なデータを含むセルを追跡する補助スタックを使用することです。最初にdata[i]
に書き込むときに、インデックスi
をスタックに追加します。スタックはスタックに追加されるにつれて増加するだけなので、気にする必要のあるジャンクは一切含まれません。
data[k]
にアクセスするたびに、k
のスタックをスキャンしてそのジャンクがあるかどうかを確認できます。しかし、それは最初の場所の配列のポイントを破って、読み取りごとにO(n)時間かかるでしょう!
これを解決するために、別の補助配列stack_check[0..n]
を作成します。この補助配列もまた迷惑メールでいっぱいです。この配列には、スタック内の要素へのポインタが含まれています。今度はdata[i]
に書き込むと、i
がスタックにプッシュされ、stack_check[i]
が新しいスタック要素を指すように設定されます。
data[k]
が良好なデータである場合、stack_check[k]
は、スタック要素がk
であることを示します。 data[k]
が迷惑メールである場合、stack_check[k]
の迷惑メールの値は、k
以外のスタック要素を指しているか、または何らかのスタック要素を指しています(k
は決してスタックに置かれていないため)。このプロパティをチェックするのはO(1)です。したがって、配列アクセスはまだ高速です。
すべてをまとめて、O(1)に配列とヘルパー構造を作成することができます。それぞれの読み書きで、指定されたセルに、私たちのヘルパーを使用して、O(1)時間のジャンクが含まれているかどうかがチェックされます。私たちが迷惑メールに上書きしている場合は、ヘルパー構造を更新して、セルを有効なデータとしてマークします。迷惑メールを読んだ場合は、問題に適した方法で処理できます。例えば、0のようなデフォルト値を返すことができます(今は初期化していないとは言えません!)、あるいは例外を投げるかもしれません。
隣接行列のスパース表現は、隣接リストに過ぎません。 –