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

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

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

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

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

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

ブログ    
ブログ    
ブログ    

推薦する

自動運転車の実現はAIと人間のゲームである

「人間がテクノロジーを生み出すペースは加速しており、テクノロジーの力は指数関数的に成長しています。指...

テクノロジートレンド年末レビュー: デロイトの 2020 年テクノロジートレンドレポートの解釈

[[348166]]導入2020年は世界にとって激動の年です。経済状況は流行病の影響を受けており、不...

...

...

AIはソフトウェアテスターの仕事を「奪う」のでしょうか?

この記事は公開アカウント「Reading Core Technique」(ID: AI_Discov...

Google 中国人がタイムクリスタルを使って何十年も昔の謎を解く!永久機関が再び自然界に出現

2021年11月30日、自然界に再び時間結晶が出現しました。タイムクリスタルは不思議な物質です。理論...

...

...

エネルギー分野における人工知能の機会と課題

エネルギー部門は、現代経済において最も強力かつ収益性の高い部門の 1 つです。しかし、ほとんどのエネ...

...

死角なしの360度!カリフォルニア大学バークレー校、中国で3DHMフレームワークをリリース:1枚の写真であらゆるビデオアクションを模倣可能

任意のポーズの写真を入力し、写真の人物に「指定された動画」の動きを真似してもらうのは簡単ではありませ...

ビッグデータと人工知能の違いすら分からないのに、あなたはまだトップへの道を歩んでいる

ビッグデータと AI は公平に比較​​できるでしょうか? ある程度は公平ですが、まずはその違いを明確...

正規化を放棄することで、ディープラーニングモデルの精度は前例のないレベルに到達しました

データを機械学習モデルに渡すときには、データを正規化する必要があることはわかっています。データの正規...

Tik Tok ダンスでは、実際の人物がカメラに映る必要はなく、1 枚の写真だけで高品質のビデオを生成できます。バイトダンスの新技術をCTOと一緒に体験する機会も

見て!今、あなたの前で踊っているのは 4 人の若い女性です。ショート動画プラットフォームで何人かのキ...

ベアリングポイント調査 - 2022 年の 5 つのテクノロジー トレンド

[[429514]]ベアリングポイントは、IT リーダーが今後 1 年間にどのテクノロジー分野に重点...