私は投稿で2つの具体的な質問を見ました:
- ツリー内で3つ以上の子を使用するデータ構造を持つことは可能ですか?もちろん、これは可能です。興味深いことに、投稿したノード構造でも可能です。
left
ポインタを最初の子へのright
ポインタであり、次の兄弟へのポインタであると考えてください。グラフの幅優先探索は暗黙的にスパニングツリーを構築するため、実際に何らかの方法で表現する場合は、このツリーを事前に順序付けて歩くことができます。
- ツリー構造を使用せずにプレオーダーウォークを実行できますか?はい、これも可能です。基本的に、DFSとBFSは概念的には違いはありません。次にアクセスするノードを維持するデータ構造があるだけです。DFSの場合、これはスタックであり、BFSの場合、これはキューです。訪問するノードを維持するデータ構造にノード番号を挿入するときにノード番号を発行すると、ツリーの事前順序ウォークが得られます(つまり、親の後にノードのすべての子を訪問します)。
2番目のポイントを少し拡張するには:木の事前注文ウォーク単に、各ノードが子ノードの前に処理されることを意味します。グラフの連結成分をトラバースするグラフ検索を実行し、各ノードに1回だけアクセスすると、暗黙のツリーが効果的に作成されます。つまり、開始ノードがツリーのルートノードになります。ノードにアクセスするたびに、アクセスされていない、つまりマークされていない隣接ノードを検索します。そのようなノードがある場合、インシデントエッジはツリーノードになり、ノードにマークを付けます。アクティブに保持されているノードは常に1つだけなので、処理されていないノードを覚えておく必要がありますが、スタックやキューなどの一部のデータ構造では(スタックを明示的に使用する代わりに、再帰を実行して、暗黙的にスタックします)。今、
これがわからない場合は、紙を一枚取り出してグラフとキューを描いてください。
- 白丸のノードとその横のノード番号
- 細い線のあるエッジ
- キューは単なる長方形で、最初は何も含まれていません
次に、ツリーのルートノードと同じノードを選択して検索の開始ノードにします。その番号をキューの最初の空の位置に書き込み、マークを付けます。つまり、ノードを埋めます。次に検索を続行します。
- キューの前に示されているノードを見て、満たされていない隣接ノードを見つけます。
- キューの後ろ(つまり、長方形の最後のノードのすぐ後ろ)にノードを追加します
- ノードにマークを付ける(つまり塗りつぶす)
- 2つのノードを結ぶ線を太くします。これは木の端になります
- マークされていない隣接ノードがそれ以上ない場合は、キュー内のフロントノードにチェックマークを付け(つまり、キューから削除し)、ノードがなくなるまで次のノードに移動します。
これで、キューの長方形には、グラフの幅優先探索によって示されるスパニングツリーのプレオーダーウォークが含まれます。スパニングツリーは、太い線を使用して表示されます。キューの長方形をスタックとして扱った場合にもアルゴリズムは機能しますが、まだ処理されていないノード間のノードがチェックされてしまうため、少し面倒になります。最初のチェックされていないノードを見る代わりに、最後にチェックされていないノード。
グラフアルゴリズムを使用する場合、アルゴリズムを視覚化することが非常に役立つことがわかりました。コンピューターに描画を維持させるのは良いことですが、紙に物を描画し、ラベルの付いた鉛筆の数でアクティブなノードを示すというローテクの代替手段も、うまくいかない場合でも機能します。
コードにコメントするだけです。入力を読み取るときは常に、データが正常に読み取られることを確認してください。ところで、あなたのコードは明らかにCのみであり、C++コードではありません。可変長配列はC++では使用できません。C ++std::vector<int> followOrder(vertexNumber)
では、の代わりにを使用しますint followOrder[vertexNumber]
。興味深いことに、コードはたとえばを使用しているため、Cでもありませんstd::queue<int>
。