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

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

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

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

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

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

ブログ    
ブログ    
ブログ    

推薦する

コードコーパス、大規模モデル、インテリジェントエージェントの魔法の杖を振ると、より強力なエネルギーが呼び出されます

熱帯雨林の杖が、ダンブルドアのようなあらゆる時代の並外れた魔法使いの伝説を生み出したのと同じように、...

...

...

Python で畳み込みニューラル ネットワークを視覚化する

ディープラーニングなどのエンドツーエンドのモデルの場合、トレーニングプロセスをどのように説明し理解す...

十分なデータを使用してモデルをトレーニングしたかどうかをどのように確認しますか?

[51CTO.com クイック翻訳]ディープニューラルネットワーク (DNN) には大量のトレーニ...

...

「顔認識」に反対する教授:最大の受益者がリスクの責任を負う

劉玉秀、ザ・ペーパーの研修記者ラオ・ドンヤン氏の抵抗により、コミュニティ内で顔認識によるアクセス制御...

...

人工知能やビッグデータ製品の開発において、特に注意すべき点は何でしょうか?

近年、人工知能は科学技術の発展の重要な方向となっており、ビッグデータの収集、マイニング、応用の技術は...

無線測定・制御、顔認識、ドローン検査などハイテクが「史上最難関の大学入試」を護衛

本人確認のための顔認識、路上の車両の無線測定と制御、空中検査を行うドローン...人々の日常生活におけ...

...

...

携帯電話に搭載された3D姿勢推定は、モデルサイズが類似モデルの1/7しかないが、誤差はわずか5cmである。

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

この病院のAI看護師は、人間の看護師の作業負荷を30%削減するためにオンライン化されました

[[270607]]看護師は医療現場を問わず需要が高いです。米国労働統計局の報告によると、看護師の求...