Skip to content

Instantly share code, notes, and snippets.

@Arnauld
Last active October 9, 2017 19:12
Show Gist options
  • Save Arnauld/00c7ed63257a1e18131e0bdf6d2fc451 to your computer and use it in GitHub Desktop.
Save Arnauld/00c7ed63257a1e18131e0bdf6d2fc451 to your computer and use it in GitHub Desktop.
Tree traversal with tail call recursion
-module(tree).
-export([main/0]).
-record(node, {
value = nil,
left = nil,
right = nil}).
%
% tc_pre_order
%
tc_pre_order(Fn, Node) ->
tc_pre_order(Fn, [Node], nil).
tc_pre_order(_, [], nil) ->
ok;
tc_pre_order(Fn, [X | Xs], nil) ->
tc_pre_order(Fn, Xs, X);
tc_pre_order(Fn, Xs, #node{value = V, left = L, right = R}) ->
Fn(V),
tc_pre_order(Fn, [R | Xs], L).
%
% tc_in_order
%
tc_in_order(Fn, Node) ->
tc_in_order0(Fn, [{node, Node}]).
tc_in_order0(__, []) ->
ok;
tc_in_order0(Fn, [{node, nil} | XS]) ->
tc_in_order0(Fn, XS);
tc_in_order0(Fn, [{node, N} | XS]) ->
#node{value = V, left = L, right = R} = N,
tc_in_order0(Fn, [{node, L}, {value, V}, {node, R} | XS]);
tc_in_order0(Fn, [{value, V} | XS]) ->
Fn(V),
tc_in_order0(Fn, XS).
%
%inorder traverse the tree and take Fn as a function to print each node
%
in_order(_, nil) ->
ok;
in_order(Fn, #node{value = V, left = L, right = R}) ->
in_order(Fn, L),
Fn(V),
in_order(Fn, R).
%
%preorder traverse the tree and take Fn as a function to print each node
%
pre_order(_, nil) ->
ok;
pre_order(Fn, {node, V, L, R}) ->
Fn(V),
pre_order(Fn, L),
pre_order(Fn, R).
%
% recursive insert to build the tree
%
insert(ND = #node{value = N, left = L}, V) when N > V ->
ND#node{left = insert(L, V)};
insert(ND = #node{right = R}, V) ->
ND#node{right = insert(R, V)};
insert(nil, V) ->
#node{value = V}.
main() ->
%
% build the tree using recursive insert function
%
TS =
[insert(insert(insert(insert(insert(insert(insert(insert(nil, 1), 2), 4), 7), 5), 6), 8), 9),
#node{value = 1,
left = #node{value = 2},
right = #node{value = 3,
left = #node{value = 4},
right = #node{value = 5,
right = #node{value = 6}}}}],
lists:foreach(fun eval_tree/1, TS).
eval_tree(T) ->
io:format("Tree is ~p~n", [T]),
F = fun(X) -> io:format("~p ", [X]) end,
%
%traverse the tree
%
io:format("~nTree traverse pre-order~n"),
pre_order(F, T),
io:format("~nTree traverse (tc)pre-order~n"),
tc_pre_order(F, T),
io:format("~nTree traverse in-order~n"),
in_order(F, T),
io:format("~nTree traverse (tc)in-order~n"),
tc_in_order(F, T),
io:format("~n--END--~n").
@Arnauld
Copy link
Author

Arnauld commented Oct 9, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment