与えられた2つのバイナリツリーが同じであるかどうかを検索する効率的なアルゴリズムは何ですか?構造と内容は同じですか?2つのバイナリツリーが等しいかどうかを確認する
答えて
それは小さな問題だが、次のように私は、以前のソリューションを適応させるだろう...
eq(t1, t2) =
t1.data=t2.data && eq(t1.left, t2.left) && eq(t1.right, t2.right)
理由はメートルということですismatchesは一般的である可能性が高いため、早期に検出してから比較をやり直すことをお勧めします。もちろん、私はショートサーキットであると仮定しています& &演算子はここにあります。
これは、構造的に異なるツリーを正しく処理し、再帰を終了することでいくつかの問題が解決されることを指摘します。基本的には、t1.leftなどのヌルチェックが必要です。一方のツリーに.leftがなくても、他方のツリーには構造的な違いがあります。両方とも空白がある場合、差はありませんが、リーフに達しました。それ以上は再帰しません。両方の.left値がNULLでない場合にのみ、サブツリーをチェックするために繰り返します。もちろん、同様のことが当てはまります。
たとえば、次のようなチェックを含めることができます。 (t1.left == t2.left)、これは、2つのツリーに対してサブツリーを物理的に共有できる(同じデータ構造ノード)場合にのみ意味があります。このチェックは、t1.leftとt2.leftが同じ物理ノードである場合、それらのサブツリー全体が同一であることを既に知っています。
ACの実装がコメントに応えて...
bool tree_compare (const node* t1, const node* t2)
{
// Same node check - also handles both NULL case
if (t1 == t2) return true;
// Gone past leaf on one side check
if ((t1 == NULL) || (t2 == NULL)) return false;
// Do data checks and recursion of tree
return ((t1->data == t2->data) && tree_compare (t1->left, t2->left)
&& tree_compare (t1->right, t2->right));
}
EDITかもしれない...これを使用して完全なツリーを比較するための
実行している時間が最も簡単(Oとして記載されていますn)ここで、nはちょっと木のサイズです。より複雑な境界を受け入れる場合は、O(最小(n1、n2))のような小さなものを得ることができます。ここで、n1とn2はツリーのサイズです。
説明は、基本的に、再帰呼び出しは左ツリーの各ノードに対して1回だけ実行され、右ツリーの各ノードに対して1回のみ作成されます。関数自体(再帰を除く)は最大でも一定量の作業しか指定しないので(ループはありません)、すべての再帰呼び出しを含む作業は、小さなツリー時間の定数と同じくらいです。
ツリーの交差点のアイデアを使用して、より複雑な小さい境界線をさらに解析することができますが、大きなOは、上限を示しています。これをコンポーネントとしてより大きなアルゴリズム/データ構造を構築しようとしない限り、おそらくこの分析を行う価値はありません。その結果、いくつかのプロパティが常にそれらのツリーに適用され、より大きなアルゴリズム。
タイガーバインドを形成する1つの方法は、両方のツリーのノードへのパスのセットを検討することです。各ステップは、L(左のサブツリー)またはR(右のサブツリー)です。したがって、ルートは空のパスで指定されます。ルートの左の子の右の子は "LR"です。有効なパスの集合をツリー内に表現する関数 "paths(T)"(数学的にはプログラムの一部ではない)を定義する。
だから我々は...
paths(t1) = { "", "L", "LR", "R", "RL" }
paths(t2) = { "", "L", "LL", "R", "RR" }
同じパス指定は両方のツリーに適用されている場合があります。そして、それぞれの再帰は、常に両方のツリーの同じ左/右のリンクに従います。したがって、再帰はこれらの集合の反復でパスを訪れ、これを使って指定できる最も厳密な境界は、その交差のカーディナリティです(再帰呼び出しごとの定数に依然としてバインドされています)。上記のツリー構造については
、我々は次のパスのために再帰を行う...
paths(t1) intersection paths(t2) = { "", "L", "R" }
ので、この場合は私たちの仕事は、非再帰的な仕事の最大3倍の最大コストに制限されtree_compare関数です。
これは通常、不必要な詳細量ですが、明らかにパスセットの交点は最小の元のツリー内のノードの数と同じくらいです。また、O(n)のnが1つの元のツリーのノード数または両方のノードの合計を参照するかどうかは、明らかに最小値または最小値のいずれよりも小さくなりません。したがって、O(n)はそのような厳密な境界ではありませんが、私たちが話しているサイズがあいまいであっても、依然として有効な上限です。
おそらく達成しようとしているものの一般的な用語はgraph isomorphismです。このページでこれを行うアルゴリズムがいくつかあります。
FWIWでは、木の同型性は線形時間で確認できます。 – ShreevatsaR
モジュロスタックオーバーフロー、
eq(t1, t2) =
eq(t1.left, t2.left) && t1.data=t2.data && eq(t1.right, t2.right)
ようなもの(これはすべてのツリー構造代数データ型の等価述語に一般化 - 構造化データのどの部分のために、そのサブ部分の各々が等しいかどうかを確認他の1のサブ部分のそれぞれに。)
ブライアンに感謝の言葉をくれてありがとう。 – Rachel
私は以下のように書いています。あなたのデータ型は(例えばない辞書やリスト)ハッシュ可能である場合に、次のコードは、ほとんどの関数型言語では、とさえPythonで動作します。(同じ構造で、すなわちTree(1,Tree(2,3))==Tree(Tree(2,3),1)
)
トポロジカル平等:
をtree1==tree2
set(tree1.children)==set(tree2.children)
が平等を命じた意味:
tree1==tree2
はtree1.children==tree2.children
が平等が既に彼らのために定義されているので、あなたは、ベースケース(葉)を処理する必要はありません
(Tree.childrenは子供の順序付けられたリストである)を意味します。
あなたは 'set(tree1.children)== set(tree2.children)'が 'Tree(0、Tree(1、Tree(2,3)))== Tree(0、Tree (1,3)、2)) '? – jfs
@ JFSebastian:正しく動作する(つまり、 "等しくない"結果を返します): '0 == 0'と'(1、(2,3))==((1,3)、2 ) '?最初に '(1、(2,3))==((1,3)、2)'をチェックしましょう。 '1 ==(1,3)'と '(2,3)== 2 'ですか?いいえ、木は原子と等しくないからです。したがって、 '(1、(2,3))==((1,3)、2)'は真実ではありません。したがって、 '(0、(1、(2,3)))==(0、((1,3)、2))'は真ではありません。アイデアは、設定された等価性は、その要素の等価性について再帰的に定義されるため、等価性チェックは本質的に再帰的であるということです。 – ninjagecko
なぜ '1 == 2'と'(2,3)==(1,3) 'チェックをスキップしますか? 'set()'定義は要素の特定の順序を意味しますか?それ以外の場合は非常に高価です(http://www.wolframalpha.com/input/?i=a%5Bn%5D+%3D%3D+1+%2B+2+a%5Bn+-+1%5D%2C + a%5B0%5D +%3D%3D + 1)。*トポロジカル*は、ノードの値が重要ではなく、ツリーの形状だけが重要であるということを意味しますが(例:トポロジスト、コーヒーカップ、ドーナツは同じものです](http://www.youtube.com/watch?v=4iHjt2Ovqag) – jfs
また、2つのトラバーサル(プリオーダー、ポストオーダー、またはインオーダー)のいずれかを実行し、両方のツリーの結果を比較することもできます。それらが同じであれば、それらの同等性を確かめることができます。
それが証明されたという事実ですので - 次のように長い間、我々が持っているように、バイナリツリーを再作成することが可能であるが:
- で、注文トラバーサルにおいて遭遇するノードのシーケンス。その後、
- プレオーダーまたはPOST-注文トラバーサル
2進木がインオーダーと同じとしている場合は、[プリオーダーまたはポスト順]列に遭遇しているノードのシーケンス、彼ら構造的にも価値観においても同等でなければならない。
各トラバーサルはO(n)操作です。トラバーサルは合計4回実行され、同じトラバーサルの結果が比較されます。 O(n)* 4 + 2 => O(n) したがって、時間の複雑さの合計順序はO(n)
- 1. 2つの項目が等しいかどうかを確認
- 2. 2つのデータフレームが等しいかどうかを確認する方法
- 3. 2つのジェネリックタイプが等しいかどうか確認してください
- 4. 2つのjsonが同等かどうかを確認してください
- 5. バイナリツリーのバランスが取れているかどうかの確認
- 6. 木が "等しい"かどうかを確認する
- 7. 2つの正規表現が等しいか同形であるかどうかを確認するライブラリ
- 8. ベクトルの長さが等しいかどうかを確認
- 9. mysqlでwheatherの2つの日付が等しいかどうかを確認する
- 10. Zabbixトリガで2つの文字列型項目の値が等しいかどうかを確認します。
- 11. 2つのTorchテンソルまたは行列が等しいかどうかを確認する方法?
- 12. Robolectricで2つのビットマップが等しいかどうかを確認する方法3.1.2
- 13. Cで2つのデバイスファイルが等しいかどうかを確認する方法は?
- 14. 2つの浮動小数点数がほぼ等しいかどうかを確認する - Numpy Python
- 15. 2つの日付が分精度と等しいかどうかを確認します
- 16. 2つのリストがPythonのタイプで等しいかどうか確認してください
- 17. 2つのstd :: functionが等しいかどうか確認してください
- 18. Ant:2つの数値が等しいかどうか確認してください
- 19. バイナリツリーが検索可能かどうかを確認してください
- 20. NUnit - すべてのプロパティが等しいかどうかを確認するアサート?
- 21. ForeignKeysが互いに等しいかどうかを確認する
- 22. リスト内の値が等しい値かどうかを確認する〜Python
- 23. 行列の対角が等しいかどうかを確認する方法
- 24. 2つの数学的回答が同等かどうかを確認してください
- 25. laravel渡されたパラメータが等しいかどうかを確認する
- 26. JS 2つのテキストフィールドが空でないかどうかを確認します。
- 27. 2つのオブジェクトの型が同じかどうかを確認
- 28. Sparkを使用して2つのHDFSデータセットが等しいかどうかを確認するにはどうすればよいですか?
- 29. url query "id"がtab-1と等しいかどうかを確認します
- 30. スキーム:2つのリストが等しいかどうか比較/チェック
となります。 – pierrotlefou
彼らは似ているかどうかを意味しますか? – Rachel
構造的に平均的に、または/および価値的に平均が等しいか? – Ashwin