指定された高さのすべてのバイナリツリーをリストするアルゴリズム


7

私は与えられた高さのすべての二分木をリストするアルゴリズムを見つけようとしました h

私はそれらを数えようとしているわけではないことに注意してください:そのような木の数はOEIS(A001699)で与えられています。

私が見ることができたすべてのアルゴリズムは、指定された数のノードのすべてのバイナリツリーをリストします。問題を解決する非常に非効率的な方法は、間にいくつかのノードを持つすべてのツリーをチェックすることによって続行されますh+1 そして 2h+11、しかしこれはまったく素晴らしいことではありません。

ポインタや参照は大歓迎です。


3
漸化式はそのようなアルゴリズムを意味します。(実際には、式自体ではなく、その証拠です。)
Yuval Filmus

@YuvalFilmusコメントありがとうございます。あなたはで提供する(OGFsを使用して)証明のような1を意味しますmath.stackexchange.com/questions/1183643/...を?私はこの分野にまったく慣れていない-遅くなってすみません。
Shiwen Yao 2016

リンクには他の数式もあります。すべての妥当な再発が機能します。
Yuval Filmus 2016年

回答:


2

コメントでほのめかされたように、二分木の再帰的構造に従ってください。

listbt(h)正確な高さのすべてのバイナリツリーをリストする関数を作成しますh

type BTree = Leaf | Node(BTree, BTree)

def listbt 0 = { [Leaf] }
|   listbt h = {
  result = []
  for T in (listbt h-1) {
    for k in (0..h-1) {
      for t in (listbt k) {
         result += Node(T, t)
         result += Node(t, T) if k < h-1 || t != T
      }
    }
  }
  return result
}

正しさは、上の基本的な帰納的証明で続きますh

あなたがこれの結果を覚えているならlistbt、それは可能な限り効率的になるでしょう。純粋な木の数と、それによってチェックの数がt != T支配します。

あなたは用語の共有利用する(つまり、リンクだけならばという注意tTではNode(t, T)なく、それらをコピーしないでください)あなたはかなりの出力の大きさを減らすことができます。BTreeただし、これは実装が不変である場合にのみ意味があります。


-1

私の最初の考えは、これはhビット整数に同型である長さhのパスから構築されたツリーのみを含むと考えていましたが、それらは必要なもののサブセットにすぎません。ただし、必要なのは、リーフレベルまで到達していないツリーで、完全でない各中間ノードを埋めることです。

つまり、列挙 22h1空でないhビット整数のセットとそれらをツリーに変換します。次に、各ツリーT、非完全な非リーフノードN(つまり、定義上、少なくとも1つのリーフへのパス上にあるため、子が1つだけ)ごとに、リーフレベルに到達しないすべての可能なサブツリーをアタッチします。 (height <height(N)-1、空のツリーを含む)。次に、TのすべてのNのデカルト積を出力します。

私の主張は、これはすべてのツリーを生成し、2回は生成しないということです。リーチ到達レベルではない条件により、1つのTで開始して、深さhの異なるリーフを持つ別のT 'に変換することが不可能になるためです。


1
それは本当に非効率的です。
Yuval Filmus
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.