二分木の再帰的および非再帰的トラバーサルアルゴリズムテンプレート

二分木の再帰的および非再帰的トラバーサルアルゴリズムテンプレート

[[423968]]

Leetcode を実践するには、いくつかのアルゴリズム テンプレートを知っておく必要があります。今回は、まず二分木の再帰的および非再帰的トラバーサル アルゴリズム テンプレートをまとめます。

バイナリ ツリーをトラバースする方法には、前方トラバース、中間トラバース、後方トラバース、レベル順トラバースの 4 つがあります。バイナリ ツリーのフロント、ミドル、バックの順序のトラバーサルでは、各トラバーサルを再帰的および循環的に実装することができ、各トラバーサルの再帰的実装は循環的実装よりも簡単です。以下に簡単にまとめておきます。私は「Code Thoughts」のハルビン工業大学の先輩の問題解決ガイドに深く感銘を受けました。そのため、以下のコードは「Code Thoughts」から一部引用したものです。

再帰

次の疑似コードは、二分木トラバーサルの再帰アルゴリズム テンプレートです。順序は中央、左、右で、前順序トラバーサルです。3 行のコード順序を変更することで、前順序、中央順序、後順序の 3 つの再帰トラバーサルを簡単に解決できます。

  1. def preorderTraversal(ルート: TreeNode) -> List[ int ]:
  2. 解像度 = []
  3. defヘルプ(ルート):
  4. ルートでない場合は戻る 
  5. res.append(ルート.val) #
  6. help( root.left ) # 左
  7. ヘルプ( root.right ) # 右
  8. ヘルプ(ルート)
  9. 戻り

これには C++ コードも用意されています。再帰アルゴリズム テンプレートには終了条件を追加する必要があります。そうしないと、再帰に入ると、深海に入るようなものになり、それ以降は、オファーは通行人になります。ソース コードのランダムな考え。

  1. void help(TreeNode * ルート、ベクトル< int > &res) {
  2. ルート == nullptr の場合 {
  3. 戻る;
  4. }
  5. res.push_back(root->val); // 中間
  6. help(root-> left ,res); // 左
  7. help(root-> right ,res); //右
  8. }
  9.  
  10.  
  11. ベクトル< int > preorderTraversal(TreeNode* ルート) {
  12. ベクトル< int > res;
  13. ヘルプ(ルート、res);
  14. resを返します
  15. }

反復

バイナリ ツリーの反復トラバーサルは、再帰トラバーサルよりも困難です。実際、スタック データ構造が使用されます。「Code Thoughts」では、マーキングにヌル ポインターを巧みに使用しています。原則として、処理されたノードをスタックに配置し、ヌル ポインターをマークとして配置します。

スタックは先入れ後出しの順序になっているため、事前順序トラバーサルの順序は左と右です。スタックに追加するときは、逆の順序で追加する必要があります。追加する各要素の後に null ポインターを追加します。Python では、代わりに None を使用することもできます。

以下は具体的な疑似コードです。インオーダートラバーサルとポストオーダートラバーサルについては、スタックにノードを追加する順序を変更するだけです。

  1. def preorderTraversal(ルート: TreeNode) -> List[ int ]:
  2. 結果 = []
  3. st=[]
  4. # 1. ルートを決定する
  5. ルートの場合:
  6. st.append(ルート)
  7. 一方、st:
  8. ノード = st.pop()
  9. ノードが None の場合:
  10. # 右、左、中央をスタックに追加し、中央、左、右を取り出します
  11. node.rightの場合: #right
  12. st.append(ノード右)
  13. node.leftの場合: #left
  14. st.append(ノード.left )
  15. st.append(ノード) #
  16. # ノードを記録するためにヌルポインタを追加します
  17. st.append(なし)
  18. それ以外
  19. # ノードはヌルポインタなので、次のノードが追加されます
  20. ノード = st.pop()
  21. 結果を追加します(node.val)
  22. 結果を返す

以下は具体的な C++ コードです。C++ ではスタックにポップした後に戻り値がないので、特に注意が必要です。

  1. ベクトル< int > preorderTraversal(TreeNode* ルート) {
  2. ベクトル< int >res;
  3. スタック<TreeNode*> st;
  4. ルートが nullptr ではない場合、st.push(root);
  5. while(!st.empty()){
  6. TreeNode* ノード = st.top ();
  7. if(ノード ​​!= nullptr){
  8. st.pop();
  9. if(node-> right ) st.push(node-> right );
  10. ノードが左にある場合、st.push(ノードが左にある)。
  11. st.push(ノード);
  12. st.push( NULL );
  13. }それ以外{
  14. // 特別な注意が必要
  15. st.pop();
  16. ノード = st.top ();
  17. st.pop();
  18. res.push_back(ノード->val);
  19. }
  20. }
  21. resを返します
  22.      
  23. }

階層トラバーサル

実際、ツリー トラバーサルには、深さ優先トラバーサルと幅優先トラバーサルの 2 種類があります。ツリーのさまざまな深さ優先トラバーサル (前順序、内順序、後順序トラバーサル) は、再帰的および非再帰的な記述方法です。ツリー内の幅優先トラバーサルは、レベルごとのトラバーサルです。

バイナリ ツリーの階層的トラバーサルでは、トラバーサルを完了するためにキュー データ構造を使用する必要があります。

Pythonの擬似コードでは、

  1. def levelOrder(root: TreeNode) -> List[List[ int ]]:
  2. # 1. ルートを決定する
  3. ルートでない場合:
  4. 戻る[]
  5. # キューにルートを追加する
  6. quene = [ルート]
  7. 出力リスト = []
  8. 一方、クエン:
  9. # 最初のステップは長さを見つけることです
  10. 長さ = len(キュー)
  11. in_list = []
  12. _が範囲(長さ)の場合:
  13. # C++では2行必要
  14. curnode = queue.pop(0) # (デフォルトではリストの最後の要素を削除します) ここではキューの先頭にある要素を削除する必要があります
  15. in_list.append(curnode.val)
  16. curnode.left場合: queue.append( curnode.left )
  17. curnode.right場合: queue.append( curnode.right )
  18. out_list.append(in_list)
  19. out_listを返す

上記の Python 疑似コードを使用して、より効率的な C++ コードを記述します。

  1. クラスソリューション{
  2. 公共
  3. ベクトル<ベクトル< int >> レベルオーダー(TreeNode* ルート) {
  4. ベクトル<ベクトル< int >> res;
  5. キュー<TreeNode*> que;
  6. // ルートを決定する
  7. root != nullptr の場合、que.push(root);
  8. while(!que.empty()) {
  9. // まずキューの長さを調べます
  10. 整数 サイズ= que.size ( );
  11. ベクトル< int > vec;
  12. // 反復してノード要素を追加する
  13. ( int i = 0 ; i<サイズ; i++) {
  14. TreeNode* ノード = que.front();
  15. que.pop();
  16. vec.push_back(ノード->val);
  17. if (node-> left ) que.push(node-> left );
  18. node-> rightの場合、que.push(node-> right ) を実行します。
  19. }
  20. res.push_back(vec);
  21. }
  22. resを返します
  23. }
  24. };

上記はツリートラバーサルテンプレートです。実際、これは本質的には深さ優先探索と幅優先探索のアルゴリズム テンプレートです。他の多くの操作はツリー探索操作に基づいています。したがって、すべてのツリー探索方法を習得することは、ツリー問題の半分を解決することと同じです。

<<:  毎日のアルゴリズム: 二分木のレベルトラバーサル

>>:  暗号化アルゴリズムの革命的な進歩、データ保護の問題を解決するか?

ブログ    
ブログ    
ブログ    

推薦する

...

ワークステーションはクライアント側の大規模モデルの「幸せな家」です

MacでSiriを呼び出したことがありますか?とにかく一度も合格していない。 AIの世界では「ベテラ...

AI画像拡大ツール、完全無料!ワンクリックで不良ピクセルにさよなら

写真は思い出を保存するための最も便利なツールの一つです。テクノロジーのおかげで、ある意味カメラとも言...

...

AIチップの過去と未来、この記事を読んでください

[[248236]]皆さんは、イ・セドルと柯潔を破った Google の「Alpha Go」をまだ覚...

小度が「画期的な」新製品を百度世界2020で初公開、CCTVと提携してスマートライフの全貌を披露

「小都小都」、「私はここにいます」 - 数百万の家族と小都の間の日常会話のシーンがCCTVニュースス...

OpenAI、中小企業向けChatGPTチームサブスクリプションサービスを開始、月額料金は1人あたり30ドル

1 月 11 日、OpenAI は小規模なセルフサービス チーム専用の新しいサブスクリプション プラ...

準備はできたか? GNN グラフ ニューラル ネットワーク 2021 年の主要なアプリケーション ホットスポット 5 つ

[[378224]]今年から始めます。グラフニューラルネットワークは研究者の間で話題になっており、こ...

ディープラーニングの19の格闘技を見てください。絶滅危惧動物の保護にも役立ちます

絶滅危惧動物を研究する上で最大の課題の一つは、その数を正確に推定することであり、各個体を追跡して詳細...

...

微分方程式と機械学習: 類似点と相違点の例

AI分野におけるモデリング手法として、微分方程式と機械学習がありますが、それぞれの利点は何でしょうか...

...

企業が生産性向上のためにAIを活用しようとする中、最高AI責任者の必要性が高まっている。

Foundry の 2023 年 AI 優先事項調査では、組織内で AI および AIGC テクノ...

世界人工知能会議が終了しました。今後、AIは私たちの生活にどのように浸透していくのでしょうか?

過去 2 年間で最もホットな話題は何かと聞かれれば、人工知能は間違いなくそのリストに載るでしょう。金...