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

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

[[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. };

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

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

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

ブログ    
ブログ    
ブログ    

推薦する

...

2024年のAIに関する5つの予測

2023 年には、AI、ML、特に GenAI があらゆるところに存在しますが、内容よりもパフォーマ...

コンピュータビジョンディープラーニングにおける8つのよくあるバグ

コンピューター ビジョンのディープラーニングでよくある 8 つのバグをまとめました。誰もが多かれ少な...

ビッグデータ、クラウドコンピューティング、人工知能が統合され、セキュリティ分野に応用されている

過去2年間、安全都市、インテリジェント交通、スノーブライトプロジェクトの継続的な発展と深化に伴い、ビ...

...

人工知能は視覚効果アーティストの役割に取って代わるでしょうか?

視覚効果 (VFX) の分野における AI の統合は、シームレスでデータ主導のアプローチを導入するこ...

大型模型シリーズ - RAGの解釈

RAG は、2023 年に最も人気のある LLM ベースのアプリケーション システム アーキテクチャ...

合理性への回帰とアプリケーションとの統合 - AI時代のモバイル技術革新カンファレンス

人工知能の出現により、ますます多くの企業がそれを業務や生産に応用しています。新しいモバイル開発技術が...

AIと機械学習でデータセンターを強化

人工知能(AI)と機械学習は、インテリジェントデータセンターにおいてますます重要な役割を果たしていま...

4つの主要な応用分野が開拓され、外骨格ロボットのブルーオーシャンが出現している

現在、ロボット産業の急速な発展に伴い、ロボット製品システムはより完成度が高まり、その用途も多様化して...

人工知能は社会に何をもたらすのでしょうか? 1つの記事でAIの変革を理解する

人類の科学技術が急速に発展する時代において、人工知能はその精密なアルゴリズムと高効率な作業能力により...

...

人工知能と教育の統合が高等教育改革を促進

[[434341]]我が国の長期的な発展と人材戦略により、質の高い人材に対する需要が急速に高まってい...

マイクロソフト、Canary チャネルの Windows Terminal ユーザーに AI チャット エクスペリエンスを提供

11月18日、マイクロソフトはWindows Terminal AIエクスペリエンスをオープンソース...

AI顔認識:スマート監視を開発する方法

顔認識技術は継続的に発展しており、スマート監視システムの開発に貢献しています。これらのシステムにより...