chandan374

chandan374

I am new to elixer, I need some help to construct binary tree from list of element(given in level order). Due to immutability i’m facing difficutly to implement this.
For ex: [1, 2, 3, -1, -1, -1, -1] will be represented as:

                  1
                /   \
              2       3

Here -1 means, node will be null.

Expected Output Format:

TreeNode{
	data: 1,
	left: TreeNode{
		data: 2,
		left: nil,
		right: nil
	},
	right: TreeNode{
		data: 3,
		left: nil,
		right: nil
	}	
}

In ruby, we can implement in this way.

def input_tree(input)
	val = input[0]
	input.shift()
	root = TreeNode.new(val)
	queue = []
	queue.push(root)
	
	while queue.size > 0
		current_node = queue[0]
		queue.shift()
		
		leftValue = input[0]
		input.shift()
	
		rightValue = input[0]
		input.shift()
		
		if leftValue != -1
			leftNode = TreeNode.new(leftValue)
			current_node.left = leftNode
			queue.push(leftNode)
		end
		
		if rightValue != -1
			rightNode = TreeNode.new(rightValue)
			current_node.right = rightNode
			queue.push(rightNode)
		end
	end
	return root
end

TIA :slight_smile:

Marked As Solved Switch mode

al2o3cr

al2o3cr

Here’s an approach that uses a pair of recursive functions:

defmodule TreeNode do
  defstruct ~w[data left right]a
end

defmodule TreeBuild do
  @nothing -1

  def run([root | rest]) do
    [[left, right]] = subnodes(1, rest)
    %TreeNode{data: root, left: left, right: right}
  end

  def subnodes(0, []), do: []
  def subnodes(count, input) do
    {roots, rest} = Enum.split(input, 2*count)

    next_count = Enum.count(roots, & &1 != @nothing)

    child_nodes = subnodes(next_count, rest)

    roots
    |> build_nodes(child_nodes, [])
    |> Enum.chunk_every(2, 2, [nil])
  end

  def build_nodes([], _, acc), do: Enum.reverse(acc)
  def build_nodes([@nothing | roots], child_nodes, acc) do
    build_nodes(roots, child_nodes, [nil | acc])
  end
  def build_nodes([root | roots], [], acc) do
    node = %TreeNode{data: root, left: nil, right: nil}
    build_nodes(roots, [], [node | acc])
  end
  def build_nodes([root | roots], [[left, right] | child_nodes], acc) do
    node = %TreeNode{data: root, left: left, right: right}
    build_nodes(roots, child_nodes, [node | acc])
  end
end

TreeBuild.run([1, 2, 3, -1, -1, -1, -1])

TreeBuild.run([5,4,8,11,-1,17,4,7,-1,-1,-1,5, -1, -1, -1, -1])

Some notes on the implementation:

  • the sample input has one fewer -1 on the end than I expected at first; this version of build_nodes is tolerant of any number of trailing -1s.
  • chunk_every is used to tidily handle cases where build_nodes returns an odd number of nodes by providing a nil for leftovers

@Eiji I believe the error in your diagram is the two -1s under the -1 that’s a right-child of 4. -1s on a given level shouldn’t consume any input values in the next level.

Also Liked

Eiji

Eiji

(…) if a node has an index i , its children are found at indices 2i+1 (for the left child) and 2i+2 (for the right) (…)

Source: Arrays at Binary tree | Wikipedia

With above writing code is really simple:

defmodule TreeNode do
  defstruct ~w[data left right]a
end

defmodule Example do
  def sample(input, index \\ 0) do
    data = Enum.at(input, index)

    unless data in [nil, -1] do
      %TreeNode{
        data: data,
        left: sample(input, index * 2 + 1),
        right: sample(input, index * 2 + 2)
      }
    end
  end
end

iex> Example.sample([1, 2, 3, -1, -1, -1, -1])
%TreeNode{
  data: 1,
  left: %TreeNode{data: 2, left: nil, right: nil},
  right: %TreeNode{data: 3, left: nil, right: nil}
}
cevado

cevado

have you tried using gb_trees from erlang?

Last Post!

chandan374

chandan374 OP

Thanks everyone for quick help.

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
dli
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app? Looking for hints regarding: Addi...
New
roeland
Kia ora, We have been using elixir-google-api to connect to Google Drive. However, with the updates to Tesla due to CVEs this is now bro...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
rahultumpala
Hello, I have an Elixir backend that implements a custom protocol over TCP. I want to load test the backend and assess the performance o...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement