elevatika
Tree traversal in elixir, pre-order, in-order, post-order What am I doing wrong?
I am learning Elixir and wanted to try implementing simple tree traversal algorithms. However, I am not getting the desired results. What am I doing wrong?
defmodule Algos do
#pre_order function, prints the root, the left then the right
def pre_order(node, nodes) do
next = [nodes | node.data]
if (node && node.left) do
Algos.pre_order(node.left, next)
end
if (node && node.right) do
Algos.pre_order(node.right, next)
end
next
end
#in_order function, prints the left, the root then the right
def in_order(node, nodes) do
if (node && node.left) do
Algos.in_order(node.left, nodes)
end
next = [nodes | node.data]
if (node && node.right) do
Algos.in_order(node.right, next)
end
next
end
#post_order function, prints the left, the right then the root
def post_order(node, nodes) do
if (node && node.left) do
Algos.post_order(node.left, nodes)
end
if (node && node.right) do
Algos.post_order(node.right, nodes)
end
[nodes | node.data]
end
end
defmodule Traverse do
def print do
root = %{
data: "A",
left: %{
data: "B",
left: %{
data: "C",
left: nil,
right: nil
},
right: %{
data: "D",
left: nil,
right: nil
}
},
right: %{
data: "E",
left: nil,
right: nil
}
}
result = Algos.pre_order(root, "")
IO.puts(result)
result2 = Algos.in_order(root, "")
IO.puts(result2)
result3 = Algos.post_order(root, "")
IO.puts(result3)
end
end
Traverse.print
The output looks as follows
[Running] elixir "/Volumes/MAC/d/Algorithms/tree_traversal.exs"
A
A
A
[Done] exited with code=0 in 3.891 seconds
Marked As Solved
NobbZ
Well you call a function f, it returns a value. Currently you do not assign that value. You can assign it by using =:
list = pre_order(node.left, next)
As far as I remember, “preorder” is basically [data] ++ pre_order(left) ++ pre_order(right), therefore this is where I would start.
def pre_order(%{data: data, left: left, right: right}) do: [data] ++ pre_order(left) ++ pre_order(right)
This provides you the generic case of the pattern match, you now need to provide the base case which breaks the recursive call. This version will crash on the leafs.
Also Liked
NobbZ
What output would you expect instead?
You don’t use the return values of th recursive calls, they won’t have any effect besides heating your room.
NobbZ
A common approach is to use either an atom that represents the empty tree, eg. nil or :empty, or to just use a empty map (%{}).
OvermindDL1
Usually what I see is either a [] for an empty/nil value and a [something] for a something value, it’s unambiguous and fast in all cases. ![]()
kokolegorille
Hello and welcome,
I did not read all the code, but this is not working as You expect, it should be an element first, then a list. If needed, You can reverse the list at the end.
[node.data | nodes]
Remember a list is [head | tail], with head being an element pushed at the head, while tails is a list.
NobbZ
You already return it. Though you are not using the returned list.







