リンクします。https://www.zhihu.com/question/19729973/answer/433057897
出典:ほとんど知っている
著者が著作権を保有。営利目的の複製については、作者に連絡して承認を得てください。非営利目的の複製については、出典を明記してください。
データ構造ではスタックとよく言われますが、スタックの違いは何ですか?アルゴリズム思考におけるこれらのデータ構造の良い使い方は何ですか?
まず最初に、通常はサービングプレートを提供します。プレートは通常1枚ずつ積み重ねられることを知っています。プレートをデータと比較します。積み重ねられたプレートはスタックのデータ構造に非常に似ています。
最後のアウトそのような構造は、スタックデータ構造、我々 、Eをとる、D、C、B、第1のメモリに格納されたデータであり、次いで、B、C、D、E。
同じヒープデータ構造の特別な種類であり、スタックは多少異なっている、ヒープメモリがある環境(例えばPythonの仮想マシンなど)の管理との言語システムのアプリケーション・スタックメモリがシステムによって自動的に割り当てられ、そしてシステム割り当てのサイズにも制限があり、このサイズを超えると、以下で定義する文字オーバーフローと同様に、メモリオーバーフローエラーが報告されます。
ヒープメモリは通常、言語ランタイム環境の管理によって割り当てられるようにPythonの仮想マシンとして、コントロールのメモリとランタイム環境:
したがって、メモリを組み合わせて関連付けることができるため、システムによって制限するのは簡単ではありません
ヒープはデータアクセスの点でスタックとは異なります。スタックは最初に出入りし、ヒープは優先度キューです(キューではなく、ヒープは通常、ツリーと見なすことができる配列オブジェクトです)。いわゆる優先度キューは、優先順位に従って要素を取り出します。たとえば、一般に夕食の席では、最初に来ても、祖父母が最初に箸を動かし、次に両親を動かしてから、次のようにします。
このように優先的に楽しむことで、その厳密な論理データ構造は次のように定義されます。
この定義で、ヒープデータ構造を使用して、heap sortというソートを実行してみましょう。まず、ソートする必要がある要素のセットを取得します。
16,7,3,20,17,8
最初にツリーを構築します。
ヒープデータ構造の定義によると、つまり、非リーフノードのデータは、その左および右の子ノードのデータより大きくも小さくもありません。
、次のように調整:
調整が上記のようになるまでは、最大が一番上にあり、下の各子ノードは親ノードより小さく、ヒープが初期化されることを意味します。ヒープ(注)をソートするために、ヒープの性質に応じて、左から右に、小さいものから大きいものに配置したいと思います。次のように配置できます。
最初に、最大かつ最後の位置を交換します
赤でマークされた要素に加えて、他のデータはヒープの性質に従って再配置されます。
赤いマークを除く最大の要素を最後まで移動し続けます
ルートノードが残るまでは、現時点でソート済みですが、上記はデータ構造ヒープを利用したソートアルゴリズムです。Pythonコードを使用して以下を実現します。
デフ heap_sort ( LST ):
def sift_down ( start 、 end ):
"" "最大ヒープ調整" ""
root = start
しばらく 真:
子= 2 *ルート+ 1
子>終了の場合:
ブレーク
もし子+ 1 <=端と LST [子供] < LST [子+ 1 ]:
子+ = 1
もし LST [ルート] < LST [子供]:
lst [ root ]、 lst [ child ] = lst [ child ]、 lst [ root ]
root =子
そうしないと:
ブレーク
#最大ヒープを作成する
以下のための開始に範囲(( LEN ( LST ) - 2 ) // 2 、 - 1 、 - 1 ):
sift_down (開始、 lenは( LST ) - 1 )
#ヒープソート
用端における範囲( lenは( LST ) - 1 、 0 、 - 1 ):
lst [ 0 ]、 lst [ end ] = lst [ end ]、 lst [ 0 ]
sift_down ( 0 、エンド- 1 )
最初に戻る
もし __name__ == "__main__" :
リスト= [ 16 、 7 、 3 、 20 、 17 、 8 ]
heap_sort (リスト)
印刷(リスト)
演算結果:
複雑さを計算した後、ヒープの並べ替えも優れた並べ替えであることがわかりました。そのスタックは、実際、Viterbiアルゴリズム(バックトラックアルゴリズム、オンライン検索を含む)を学習するときにマルコフチェーンがあることを突然思い出しましたスタックのデータ構造がこのアルゴリズムのアイデアに対応していることがわかりました。実際の例を書いて見てみましょう。最初に、何がバックトラックされているかを見てみましょう。例を挙げましょう。
次の図に示すように、迷路で食べ物Tを見つけたい小さなアリPがいます。これを見つける方法は次のとおりです。各フォークをノードとして取得して記録します。アリがノード1から始まり、2、3、4を追跡するとします。それは行き止まりなので、ノード1に戻ります。戻るプロセスはバックトラックです。ノード5に到達すると、壁に戻り(バックトラック)、左右に戻ります(バックトラック)。ダウンしているときだけ食べ物を見つけます。 。
コードの実装を容易にするために、壁に1、行く場所に0、食べ物に666、そして迷路全体のマトリックスを使用します。
考えやアイデアはこれです:
1.小さなアリが歩いた分岐点を記録する
2.小さなアリがたどった経路を記録する(スタックデータ構造を使用)
3.小さな蟻が道路が通行できないことを発見した場合、または同じ分岐点に遭遇した場合、Yanyuan Roadが戻ります(パスデータはスタックデータから取り出されます)。分岐点に戻ると、分岐点の方向にアクセスできない道路のデータがマークされます。食べ物が見つかるまで、マークされていない方向に進みます(両方がマークされている場合は、元の方法に戻ります)。
特定の実装コードは掲載しませんが、これはバックトラッキングアルゴリズムでのスタックデータ構造のアプリケーションです。
ははは、一日投げた後、兄貴が間違いを指摘して一緒に進歩してくれることを願っています。
参考書:
アルゴリズム入門第3版
Pythonデータ構造