Prolog, reconstruct BST trees from inorder list

后端 未结 2 357
误落风尘
误落风尘 2021-01-18 16:28

We well know inorder implementation for BST tree.

inorder(nil, []).
inorder(t(Root, L, R), List) :-
    inorder(L, ListLeft),
    inorder(R, Lis         


        
相关标签:
2条回答
  • 2021-01-18 16:57

    First, let us use a Definite Clause Grammar (dcg) for relating trees to lists:

    inorder(nil) --> [].
    inorder(t(Root, L, R)) -->
        inorder(L),
        [Root],
        inorder(R).
    

    The trick I will now apply is described in Ulrich Neumerkel's dissertation in Taming Left Recursion.

    "... we add another state for the number of tokens that can be used by newly encountered nonterminals. The number of tokens that will be read by the terminals within a single rule are therefore reserved in advance."

    In our case:

    inorder(nil, Es, Es) --> [].
    inorder(t(Root, L, R), [_|Es0], Es) -->
        inorder(L, Es0, Es1),
        [Root],
        inorder(R, Es1, Es).
    

    Sample query (Ls omitted):

    ?- Ls = [1,2,3], phrase(inorder(Tree, Ls, _), Ls).
    Tree = t(1, nil, t(2, nil, t(3, nil, nil))) ;
    Tree = t(1, nil, t(3, t(2, nil, nil), nil)) ;
    Tree = t(2, t(1, nil, nil), t(3, nil, nil)) ;
    Tree = t(3, t(1, nil, t(2, nil, nil)), nil) ;
    Tree = t(3, t(2, t(1, nil, nil), nil), nil) ;
    false.
    

    Another way to solve such issues is to use your Prolog system's tabling mechanism.

    0 讨论(0)
  • 2021-01-18 17:01

    If you like the trick I've proposed here, the only change required could be

    :- use_module(carlo(snippets/when_)).
    
    inorder(t(Root, L, R), List) -:- ...
    

    and now

    ?- inorder(T,[1,2,3]).
    T = t(1, nil, t(2, nil, t(3, nil, nil))) ;
    T = t(1, nil, t(3, t(2, nil, nil), nil)) ;
    T = t(2, t(1, nil, nil), t(3, nil, nil)) ;
    T = t(3, t(1, nil, t(2, nil, nil)), nil) ;
    T = t(3, t(2, t(1, nil, nil), nil), nil) ;
    false.
    
    0 讨论(0)
提交回复
热议问题