web-dev-qa-db-ja.com

スタックとキュー、なぜですか?

配列/リストの代わりにスタックまたはキューデータ構造を使用する理由とタイミングスタックまたはキューを使用する方が良い状態の例を示してください。

36
Alon Gubkin

配列やリストよりも特定の方法でデータを管理するのに役立つからです。

キューは先入れ先出し(FIFO)

スタックは後入れ先出し(LIFO)

配列とリストはランダムアクセスです。それらは非常に柔軟性があり、簡単に破損します。データをFIFOまたはLIFOとして管理する場合は、既に実装されているコレクションを使用するのが最善です。

40
Paul Sasik

カフェテリアに行ったことがありますか?プレートのスタックを見ましたか?クリーンプレートがスタックに追加されると、一番上に配置されます。プレートが取り外されると、上部から取り外されます。したがって、これは後入れ先出し(LIFO)と呼ばれます。コンピュータースタックはそれに似ていますが、数値を保持する点を除き、必要に応じて配列またはリストから1つを作成できます。 (プレートのスタックの下部にスプリングがある場合、上部に「プッシュ」し、プレートを取り外すと「ポップ」します。そこから言葉が出てきます。)

カフェテリアでは、後ろに行き、皿を洗います。彼らは、片方の端に洗浄すべきプレートを置き、同じ順序でもう一方の端から出てくるコンベヤーベルトを持っています。それはキューまたは先入れ先出し(FIFO)です。必要に応じて、配列またはリストからそれらのいずれかを作成することもできます。

彼らは何のために良いですか?さて、ツリーデータ構造(逆さまになっていることを除けば木でできた本物のツリーのようなもの)があり、すべての葉を印刷するために、それを完全に通り抜けるプログラムを書きたいとします。

1つの方法は、depth-first walkを実行することです。トランクから始めて最初のブランチに行き、次にそのブランチの最初のブランチに行く、というように、葉に着くまで印刷します。しかし、次のブランチに行くにはどのようにバックアップしますか?さて、ブランチを下るたびに、スタック内の情報を「プッシュ」し、バックアップするときに「ポップ」して、それが次にどのブランチを取るかを教えてくれます。それが、各ポイントで次に行うブランチを追跡する方法です。

別の方法は幅優先ウォークです。トランクから始めて、トランクからすべてのブランチに番号を付け、それらの番号をキューに入れます。次に、もう一方の端から数字を取り出し、そのブランチに移動します。itから分岐するすべてのブランチに対して、再び番号を付け(最初のものと連続)、それらをキューに入れます。これを繰り返していくと、最初に幹から1枝離れた枝を訪れます。次に、トランクから2分岐先にあるすべての分岐を訪問します。最終的に葉に到達し、それらを印刷することができます。

これらは、プログラミングにおける2つの非常に基本的な概念です。

52
Mike Dunlavey
  1. 入れた順番で物を出したい場合は、キューを使用します。
  2. スタックを使用するのは、入れたときと逆の順序で物を取り出したいときです。
  3. リストを使用するのは、いつ入れたとしても(そして自動的に削除されたくない場合でも)、何かを取り出したいときです。
15
Kaleb Brasee

データ構造に特定の使用パターンを適用する場合。つまり、問題をデバッグしているときに、誰かがリストの中央に要素をランダムに挿入して不変式を台無しにしたかどうかを気にする必要はありません。

8
Terry Mahaffey

他の人がすでに言及した使用法の実施とは別に、パフォーマンスの問題もあります。配列またはリスト(ArrayList)の先頭から何かを削除する場合、通常はO(n)時間かかりますが、キューの場合はO(1) time。多くの要素がある場合、それは大きな違いを生む可能性があります。

6
Mark Byers

配列/リストとスタック/キューは、相互に排他的な概念ではありません。実際、スタックやキューの実装は、ほぼ確実に内部で配列またはリストを使用しています。

配列およびリスト構造は、データの格納方法の説明を提供し、構造に対する基本的な操作の複雑さを保証します。

スタックとキューは、要素が挿入または削除される方法の高レベルの説明を提供します。 FIFOキューの場合、FILOスタックの場合。

例えば。メッセージキューを実装する場合は、キューを使用します。ただし、キュー自体が各メッセージをリストに格納する場合があります。リストの先頭に追加するメッセージを「プッシュ」し、リストの最後から取得するメッセージを「ポップ」します。

5

それは意図の問題です。多くの場合、スタックとキューは配列とリストを使用して実装されますが、要素の追加と削除はより厳密に定義されます。

3
Mark Ransom

スタックとキューは、配列自体よりもコレクションを処理するためのより高度な方法であり、コレクション内で要素が動作する方法に順序を確立しません。

スタック(LIFO-先入れ先出し)およびキュー(FIFO-先入れ先出し)は、要素がコレクションに挿入されたりコレクションから削除されたりする順序と順序を確立します。

配列またはリンクリストをストレージ構造として使用して、スタックまたはキューパターンを実装できます。または、これらの基本構造を使用して、バイナリツリーや優先度キューなどのより複雑なパターンを作成します。これにより、要素の挿入と削除の順序だけでなく、コレクション内での並べ替えも行われます。

2
jmayor

スタックまたはキューは論理データ構造です。物理的な構造(リスト、配列、ツリーなど)でカバーの下に実装されます

必要に応じて「独自にロール」することも、すでに実装されている抽象化を利用することもできます。

1
Joe

スタックとキューはどちらも、アプリケーションの要求に応じて使用されるメモリアクセスの概念だと思います。一方、配列とリストは2つのメモリアクセス技術であり、stack(LIFO)とqueue(FIFO)の概念を実装するために使用されます。

1
deepak Gupta

配列よりもスタックで概念化、書き込み、読み取りが簡単なアルゴリズムがあります。データ構造自体が前提となるため、制御ロジックと反復子が少ないクリーンなコードを作成します。

たとえば、スタックを使用した場合、逆の順序でポップする要素をプッシュした配列での冗長な「逆」呼び出しを回避できます。

0
Wadih M.

質問はあいまいです。なぜなら、配列またはリンクされたデータ構造を使用して、スタックまたはキューの抽象データ型を表現できるからです。

スタックまたはキューのリンクリスト実装と配列実装の違いには、配列と動的データ構造の基本的なトレードオフがあります。

リンクされたキュー/リンクされたスタックには、合理的な実装で柔軟で高速な挿入/削除がありますが、アレイよりも多くのストレージが必要です。挿入/削除は、スペースがなくなるまでアレイの両端で安価です。キューまたはスタックの配列実装では、元の構造をより大きな構造にコピーする必要があるため(またはオーバーフローエラーで失敗するため)、サイズ変更にさらに作業が必要になります。

0
JasonTrue