技術共有

データ構造に関する注意: バイナリ ツリー スレッド

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

バイナリ ツリーはノードで構成される重要なデータ構造であり、各ノードには最大 2 つの子ノードがあります。場合によっては、バイナリ ツリーを走査してそのすべてのノードにアクセスする必要があります。ただし、バランスが取れていないバイナリ ツリーでは、通常の走査方法では非効率が生じる可能性があります。この問題を解決するには、「スレッディング」と呼ばれる手法を使用して、トラバーサル プロセスを最適化します。

1. バイナリ ツリー スレッドとは何ですか?

バイナリ ツリーのスレッド化とは、バイナリ ツリーをスレッド化されたバイナリ ツリーに変換するプロセスを指します。手がかりバイナリ ツリーは、元のバイナリ ツリーに 2 つのポインタ、ltag と rtag を追加します。これらは、それぞれ左の子と右の子の先行者と後続者を指します。これにより、順序通り、事前順序、および順序後のトラバースが簡単に可能になります。

2. バイナリツリーのスレッド化を実装するにはどうすればよいですか?

  1. 中間シーケンスのスレッド化

順序どおりのスレッディングは、順序どおりのトラバーサル アルゴリズムを変更することで実現されます。ノードにアクセスすると、そのノードとその前のノードの間で手がかり情報が接続されます。具体的な手順は次のとおりです。

  • 現在訪問しているノードの先行ノードを記録するために使用されるポインター pre を初期化します。
  • ノードごとに、バイナリ ツリー内の各ノードを走査します。
    • 最初に訪問したノードの場合、その lchild は pre に設定され、ltag は 1 に設定されます。
    • 先行ノードが決定されている場合 (つまり、pre が空でない場合)、その rchild は pre に設定され、rtag は 1 に設定されます。
    • pre を現在のノードに更新します。
  1. 予約注文のキューイング

先行手がかりと中途手がかりの考え方は似ていますが、愛の魔法陣のドロップの問題に注意する必要があります。 ltag=0 の場合、左側のサブツリーを事前順序で見つけることができます。具体的な手順は次のとおりです。

  • 現在訪問しているノードの先行ノードを記録するために使用されるポインター pre を初期化します。
  • ノードごとに、バイナリ ツリー内の各ノードを走査します。
    • 最初に訪問したノードの場合、その lchild は pre に設定され、ltag は 1 に設定されます。
    • 先行ノードが決定されている場合 (つまり、pre が空でない場合)、その rchild は pre に設定され、rtag は 1 に設定されます。
    • pre を現在のノードに更新します。
    • ltag=0 の場合、プリオーダー スレッドは左側のサブツリーで再帰的に実行されます。
  1. 注文後の手がかり

ポストオーダー スレッドも同様の考え方に従いますが、最後のノードの rchild と rtag を処理するときは特別な注意を払う必要があります。具体的な手順は次のとおりです。

  • 現在訪問しているノードの先行ノードを記録するために使用されるポインター pre を初期化します。
  • ノードごとに、バイナリ ツリー内の各ノードを走査します。
    • 最初に訪問したノードの場合、その lchild は pre に設定され、ltag は 1 に設定されます。
    • 先行ノードが決定されている場合 (つまり、pre が空でない場合)、その rchild は pre に設定され、rtag は 1 に設定されます。
    • pre を現在のノードに更新します。
    • 最後のノードに遭遇すると、その rchild は pre に設定され、rtag は 1 に設定されます。

3. 間違いやすいポイント

バイナリ ツリー スレッドの実装プロセスにおいて、一般的にエラーが発生しやすい点は次のとおりです。

  1. 最後のノードの rchild と rtag の特別な処理は無視されます。
  2. 予約スレッドの処理中に、愛の魔法陣のドロップの問題が正しく処理されませんでした。
  3. ポインタ pre が適切に初期化または更新されていません。

4. まとめ

バイナリ ツリー スレッドは、トラバーサル戦略を最適化するための効果的な方法です。追加のポインターを追加し、トラバーサル アルゴリズムを変更することで、バイナリ ツリー内のすべてのノードにより効率的にアクセスできます。実際のアプリケーションでは、コードの正確さと安定性を確保するために、上記のよくある間違いのいくつかを避けるように注意する必要があります。