elevatika

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

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

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

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

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. :slight_smile:

kokolegorille

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

NobbZ

You already return it. Though you are not using the returned list.

Where Next?

Popular in Questions Top

bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New

Other popular topics Top

sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

We're in Beta

About us Mission Statement