序章
指定された数値のリストから二分探索木の視覚的表現を作成する HTML5 Web アプリケーションを構築しています。
現在、ツリーの最大深度 (ベース 0 値) に基づいて、各行のノード間の視覚的な間隔を計算するアルゴリズムがあります。
offset = 50
offset *= pow(2, maxDepth - currentDepth)
ここから、ノードの位置は、このオフセットとその親の x 位置を使用して決定されます。
このアルゴリズムは、あらゆる深さの可能な限り広いツリーに常に対応できるため、うまく機能します。ただし、これにより、ツリーが不必要に広くなる場合もあります。
例
左へのツリー分岐 (広すぎる):
左へのツリー分岐 http://f.cl.ly/items/0c0t0L0L0o411h092G2w/left.png
両側に分岐するツリー (左側と右側が接近している可能性があります)。
両側に分岐するツリー http://f.cl.ly/items/0r3X1j0w3r1D3v1V1V3b/left-right.png
理想的には、上のツリーは、以下に示すように、幅が狭く、側面がまっすぐなピラミッドのような形にする必要があります。
バランスの取れたツリー (アルゴリズムが最適に機能する場合):
バランスの木 http://f.cl.ly/items/203m2j2i3P1F2r2T3X02/balanced.png
実装
プロパティ
Node モデルからノードを作成するために Backbone.js を使用しています。各ノードには次のプロパティがあります。
- 親(親ノード)
- left (左の子ノード)
- right (右の子ノード)
- x (ピクセル単位のノードの x 位置)
- y (ピクセル単位のノードの y 位置)
上記のxおよびyプロパティは、ノードの分岐元の方向に基づいて計算されます。
if (parent.get('left') === node) {
x = parentX - offsetX;
y = parentY + offsetY;
} else if (parent.get('right') === node) {
x = parentX + offsetX;
y = parentY + offsetY;
}
この時点で、xプロパティとyプロパティは、ノードの配置に使用される正確な値です (それぞれがコンテナー要素内で絶対的に配置されます)。
メソッド
- getDepth() (ノードのベース 0 深度を返します)
- getMaxDepth() (ツリーの最後の行の深さを返します)
- getRow(n) (深さ n のすべてのノードの配列を返します)
質問
したがって、私の質問は簡単です:
二分木の美的幅を最小化するための最適なアルゴリズムは何ですか?