Walking Trees Backwards

Alex Tweedly alex at tweedly.net
Thu Sep 11 21:21:53 EDT 2008


David Bovill wrote:
> *Task*
> I want to put an indented outline (more generally a tree structure) into an
> array.
>
>   
I suspect I've mis-understood your problem .... my "solution" seems so 
straightforward that I may be missing some important part of the desired 
data structure. So I'll re-state the problem in my own words, and then 
give my attempt to solve it  - and hopefully if there is something major 
missing, that should be clear.

Input : an indented outline of text.

Output : a data structure which allows easy (quick, efficient, ....) 
access to parent and children nodes of an arbitrary node, thereby making 
it easy to write general (possibly recursive) functions and handlers.

[Aside - often recursion is a good tool to *think* about a problem, but 
the implementation can be sequential .... ]

Data structure :  3 arrays, indexed by the line number (node number):
   i, 'text' : the text of that node
   i, 'parent' : the line number of its parent
   i. 'children : a TAB-separated list of line numbers of its children.


Given this, it is easy to write the base functions needed to build 
arbitrary tree-functions.

function getParent pArray, pNode
    return pArray[pNode, 'Parent']
end getParent

function getChildren pArray, pNode
   return pArray[pNode, 'Children']
end getChildren

for example - print out all immediate children ...

put getChildren(Data, thisnode) into tChildren
repeat for each item tChild in tChildren
      put Data[tChild, 'Text'] & CR after field 'Output'
end repeat

So - a very simple data structure to build .... code is straightforward 
if a little bit tricky

[Sorry - I have a stack ready to put on RevOline but RevOnline has 
decided I need a new key to share stacks, so here is the code in-line ...]
 
(note - only tested a little bit)

> function buildTree pInput
>    # given indented outline of a 'forest' (i.e. multiple rooted trees) 
> build the tree-like data structure
>    set the itemDel to TAB
>    put empty into lParents
>    put 0 into lCurNode # the top-level pseudo-node
>    put -1 into lCurDepth  # -1 to allow for the top-level pseudo-node
>    put 0 into lCount
>    repeat for each line L in pInput
>
>       put getDepth(L) into tDepth
>       if tDepth < lCurDepth then
>          # we have popped back up 1 or more levels
>          put tDepth into lCurDepth
>          if tDepth = 0 then
>             put 0 into lCurNode
>          else
>             #put item tDepth+2 of lParents into lCurNode
>             put lCount into lCurNode
>
>          end if
>       else
>          if tDepth = lCurDepth then
>             # another node at the same level - no change needed
>             put lCount into lCurNode
>          else
>             if tDepth > lCurDepth+1 then # badly formed input  !!
>                # should probably do something more extreme here
>                return empty
>             end if
>             # so we are here with a new increase in indent level
>             put lCurNode & TAB after lParents
>
>          end if
>       end if
>       put L into Data[lCount, 'text']
>       put item -1 of lParents into tParent
>       put tParent into Data[lCount, 'parent']
>       put lCount & TAB after Data[tParent, 'children']
>       put tDepth into lCurDepth
>    end repeat
>    return Data
> end buildTree

Hope that does something like what you wanted,
-- Alex.



More information about the use-livecode mailing list