Bo2SS

Bo2SS

2. スタックとキュー

コースの内容#

キュー#

  • FIFO(First In First Out)、LILO。並び順を区別する
  • 順序構造であり、連続したストレージスペースが必要(ただし、リンクリストでも実装可能)

構造の定義#

  • 連続したストレージスペースが必要
  • 容量
  • キューヘッド、キューテール
  • + 要素数:キューが満杯かどうかを判断し、循環キューで偽のオーバーフロー問題を解決するために使用
  • データ型

構造の操作#

  • キューから取り出す
    • ヘッド - 1
    • 要素数 - 1
  • キューに追加する
    • テール + 1
    • 要素数 + 1
  • ❗偽のオーバーフロー
    • 要素を保存できなくなる
    • 実際にはまだ満杯ではないかもしれない:キューヘッドに空きがあるため
    • 解決策:循環キュー
      • テールが最後まで行ったら、キューの先頭に戻る
      • 位置を決定するために剰余演算子を使用:(テール + 1) % 長さ
  • 容量の拡張:真のオーバーフローが発生した場合、コードのデモを参照してください

スタック#

  • FILO(First In Last Out)、LIFO。本の箱に似ているが、片方は封鎖されている
  • 順序構造でもある

構造の定義#

  • 連続したストレージスペースが必要(サイズ制限あり)
  • 容量
  • スタックトップポインタ【top】:空のスタックの場合、top = -1、0 は適切ではない
  • データ型

構造の操作#

  • スタックから取り出す:top - 1 // 空の場合は判定が必要
  • スタックに追加する:top + 1、値を保存する // 満杯の場合は判定が必要

応用#

  • 画像
  • DFS と BFS の詳細は「面接と筆記試験のアルゴリズム上」- 6 検索トピックを参照

  • モノトニックスタック、モノトニックキューは自己学習してください

授業の練習#

LC-20: 有効な括弧#

画像

  • キーポイントは考え方です:大きな問題を小さな問題に変換する方法
    • 一種類の括弧だけの場合、どのように対処しますか?スタックを使用せずに完了できますか?
    • アイデア:左括弧の数と右括弧の数だけを記録すれば良い
      • 任意の位置で、左数 >= 右数
      • 最後の位置で、左数 == 右数
      • 画像
      • 実際には、左括弧に遭遇すると + 1、右括弧に遭遇すると - 1 の操作を行うだけで十分です
        • 任意の位置で、top >= 0
        • 最後の位置で、top == 0
    • この + 1、-1 の操作は、スタックの push と pop に関連付けることができますか?
    • 一回の括弧のマッチングは、スタックの push と pop を一回行うことと同等です
    • 括弧内の括弧は完全に含まれる関係です
    • 分割統治の考え方もあります
  • スタック:完全に含まれる関係を持つ問題を処理できます
  • コード
    • 「面接と筆記試験のアルゴリズム上」- 5 STL「コンテナ」の使用と練習 - HZOJ-378 の解説を参照してください
    • C 言語では、まずデータ構造であるスタックを実装し、その後スタックを使用して問題を解決します

コードデモ#

キュー#

  • 画像
  • 画像

一部の結果

  • 画像
  • テールの定義には 2 つの方法があります

    • ①最後の要素のアドレスを指す
    • 最後の要素の次のアドレスを指す(このコードの選択)
  • 循環キューを使用すると、偽のオーバーフローの現象はもはや存在しません

  • ただし、真のオーバーフローの場合はどうすればよいですか?👇

+ 容量の拡張#

循環キューに対する容量の拡張

  • 3 つの動的メモリ割り当て方法【malloc、calloc、realloc】のうち、どれを使用しますか?

  • 🆒malloc、calloc のどちらでも使用できますが、

  • ❗以前使用していた realloc はうまく動作しません

    • 循環キューのテールは、ヘッドの後ろではなく、テールとヘッドが重なっている可能性があります
    • 例:キューがいっぱいの場合、ヘッド、テール(ここではテールは最後の要素の後)が次の位置にあるとします。この場合、容量を倍に拡張した後、キューの push と pop はどうなりますか?
    • image-20201202094139099
    • この場合、ヘッド→テールの間に多くの空の値が挿入されます。なぜなら、realloc は値を元の順序で移動するため、拡張部分にはまだ値がありません
    • では、ヘッドからテールまでの出列 [間には多くの空の値が含まれています]、またはテールからの入列 [テールの位置にはまだ出列していない要素があります] は、どのような問題がありますか?
  • 一方、malloc で空間を割り当て、元のキューをヘッドからテールまで順番に移動するだけで十分です。つまり、ヘッドをインデックス 0 に手動で調整するだけです。次のように、ヘッドとテールポインタの調整が重要です!

    • image-20201202094256207
  • コード

    • 画像
    • ポインタを正しい順序に調整することが重要です

スタック#

  • 画像
  • 画像
  • 画像

72 行目、pop 操作は top - 1 だけで十分です
109 行目、printf 内に実行待ちのコマンドがある場合、順序に注意が必要です
* 呼び出しの順序は、システムスタックの設計に関連しています
* 参考:printf 函数参数从右至左压栈-CSDN;printf 压栈出栈-CSDN
* この右から左への方法は、コンパイラやマシンによって異なるものではありません
* ローレベルのことであり、深くは追求しません
* 【結論】 printf の引数に実行待ちのコマンドがある場合は、できるだけ分けて書くべきです
106 行目、出栈前に空の場合に注意する必要があります。そうしないと、top = -1 で問題が発生します
* 初回の出力結果は安全です
* 画像

  • ❓スタックが存在するかどうかを確認するために、empty と top を呼び出す前に、関数内で NULL の判定を行うべきです
    • ただし、他の操作は基本的に NULL の判定がありますが、プログラムの分割を容易にするためのものであり、細かく考える必要はありません
    • すべての操作に NULL の判定を含めることもできます

追加の知識#

  • システムスタック
    • スタックでもあり、サイズは 8MB です
    • 再帰時に使用されるのはシステムスタックです

ヒント#

  • 画像

コースの速記#

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。