algorithm - Is there any locality-preserving way to flatten a binary tree? -


short version:

it possible flatten 2d space 1d space such if 2 points on 2d space close together, mappings 1d close together. similarly, there way map arbitrary position in binary tree, flat index in array, such if 2 nodes close on tree, close on array?


long version:

let tree type of tagged binary trees.

                            /     \            b       c           / \     / \          d   e   f   g         / \ / \ / \ / \         h j k l m n o 

a position on in tree can given bit string 0 means go left, 1 means go right , empty string root (a). example, 011 points k on tree above. moreover, let distance between 2 nodes number of steps takes go 1 another.

what map f :: bitstring -> nat node locations (bitstrings) natural numbers such if distance(a, b) small, |f(a) - f(b)| small?

i think tilmannz's answer (which uses infix ordering) it's going get. consider every node in binary tree, apart root, has 3 neighbors, , in 1d memory layout, 2 of them can distance of 1 away. also, not many other useful orderings come mind.

i've written small perl script compares default ordering depth-first prefix ordering , infix ordering. can throw output @ gnuplot following plot (edit: included van-emde-boas layout): plot showing memory locality of different node orderings

you can see original ordering has relatively bad locality small tree distances, , both prefix , infix orderings better. infix ordering produces best behaviour of three, though (e.g., nodes @ tree distance of 3 on average 6 memory indices apart). linear curve, should indicator cannot better. v.e.b. layout mentioned in comments not @ least smaller node distances, according distance criterion.

for sake of completeness, here's (somewhat quick , dirty) script used:

#!/usr/bin/perl # compares node distances in memory different layouts of following # binary tree: #                      #                  /       \ #              b               c #            /   \           /   \ #          d       e       f       g #         / \     / \     / \     / \ #        h     j   k   l   m   n   o #       / \ / \ / \ / \ / \ / \ / \ / \ #       p q r s t u v w x y z 0 1 2 3 4  # calculates real node distance. sub dist($$) {   ($i, $j) = @_;   return 0 if ($i == $j);   ($j,$i) = ($i,$j) if ($i > $j);   # $i<$j. go 1 larger node.   return 1 + dist($i, ($j-1)>>1); }  # determines average memory distance nodes function of tree distance. sub get_dists($$) {   $tree = shift;     # original tree ordering   $locality = shift; # locality-based ordering    %dists = ();   %counts = ();    (my $i=0; $i<length($tree); $i++)   {     (my $j=$i; $j<length($tree); $j++)     {       # find location of $i , $j in locality-based ordering.       $ni = substr($tree, $i, 1);       $nj = substr($tree, $j, 1);       $it = index($locality, $ni);       $jt = index($locality, $nj);       $d = (($i <= $j) ? ($j-$i) : ($i-$j));       $dt = (($it <= $jt) ? ($jt-$it) : ($it-$jt));       $treedist = dist($i, $j);       $dists{$treedist} += $dt;       $counts{$treedist}++;     }   }   foreach $k (sort keys %counts)   {     $dists{$k} /= $counts{$k};   }   return %dists; }  $tree = "abcdefghijklmnopqrstuvwxyz01234";    # original (breadth-first prefix) ordering $prefix = "abdhpqirsejtukvwcflxymz0gn12o34";  # depth-first prefix ordering $infix = "phqdrisbtjuevkwaxlyfzm0c1n2g3o4";   # infix ordering $veb = "abcdhpqirsejtukvmflxymz0gn12o34";     # v.e.b. layout (hope got right)  %original_dists = get_dists($tree, $tree); %prefix_dists = get_dists($tree, $prefix); %infix_dists = get_dists($tree, $infix); %veb_dists = get_dists($tree, $veb);  print "set key top left;\n"; print "set title 'locality ratios';\n"; print "set xlabel 'tree distance';\n"; print "set ylabel 'avg. memory distance';\n";  print "plot '-' w lp title 'original', '-' w lp title 'prefix ordering', '-' w lp title 'infix ordering', '-' w lp title 'van-emde-boas layout';\n";  foreach $k (sort keys %original_dists) {   print "$k $original_dists{$k}\n"; } print "e\n"; foreach $k (sort keys %prefix_dists) {   print "$k $prefix_dists{$k}\n"; } print "e\n"; foreach $k (sort keys %infix_dists) {   print "$k $infix_dists{$k}\n"; } print "e\n"; foreach $k (sort keys %veb_dists) {   print "$k $veb_dists{$k}\n"; } print "e\n"; 

Comments

Popular posts from this blog

Hatching array of circles in AutoCAD using c# -

ios - UITEXTFIELD InputView Uipicker not working in swift -

Python Pig Latin Translator -