Binary tree Breadth-first search - ocaml

I'm using OCaml. I have type:
type 'a bt = Empty | Node of 'a * 'a bt * 'a bt;;
Also I have example BST:
let tree = Node(1,Node(2,Node(4,Empty,Empty),Empty),Node(3,Node(5,Empty,Node(6,Empty,Empty)),Empty));
I need to write function: breadthBT : 'a bt -> 'a list which will be Breadth-first search traversal. For above example tree it should returns [1; 2; 3; 4; 5; 6]
How to write that function? I can write only following function which uses DST :
let rec breadthBT tree =
if tree=Empty then []
else let Node(w,l,r)=tree in (w::breadthBT l)#breadthBT r;;
Above function returns (for example tree) [1; 2; 4; 3; 5; 6]. But I can't write function which uses BFS. Could you help me?

It is not a compilable solution. Just a tip.
You should iterate from top level root node to deep level nodes. Let our function receives accumulator for the answer and list of nodes (your 'a bt values) as second parameter. You can map this list by getting first element of triple and than you receive next part of answer. Also you need to evaluate next level of tree. For every node there are at most two descendants. You can map your list and apply _a_function_to receive list of descendants. It will be next level of your tree. And than --- recursion.
A will not specify this _a_function_. Try to study what is concatMap in google.
Happy hacking!

Imagine you stick your nose to the tree. Is it possible to traverse the tree in the breadth-first manner without bookmarking positions in your notepad? No, because the order can make you jump from one branch to another unrelated branch. So you need a notepad with "remaining positions to visit". You pick the next remaining position from the notepad and jump to it blindly. Since you erase visited positions from the notepad, you are at a node you have not visited yet. And since you cannot get up the tree without visiting intermediate nodes, you haven't visited the two nodes now above you. But you resist the instinct to climb the branches directly -- heck, this is breadth first order. You do not want to forget about these two unvisited nodes, so you want to put them into the notebook. Where do you put them, in front of the notebook or on its back? On the back of course, otherwise you would pick one of them immediately and that's what we want to avoid. Et voila: your notepad is a FIFO queue of nodes, which you keep (i.e. pass) around as an accumulator, but also consume to pick a subtree to visit.

Related

Struggling to extract a section of a list in Haskell

I am trying to implement a basic function but I'm out of practice with Haskell and struggling so would really appreciate some help. My question is specifically how to select a section of a list by index. I know how to in other languages but have been struggling
[ x | x <- graph, x!! > 5 && x!! <10 ]
I have been fiddling around with basic list comprehension similar to what is above, and while I know that isn't right I was hoping a similarly simple solution would be available.
If anyone wants more information or felt like helping on the further question I have included more information below, thanks!
type Node = Int
type Branch = [Node]
type Graph= [Node]
next :: Branch -> Graph -> [Branch]
This is the individual question for the "next" function
This is the general set up information but most importantly that the graph is represented as a flattened adjacency matric
Apologies for the two pictures but it seemed the best way to convey the information.
As pointed out in the comments !! does not give you the index of a value in the way it seems you expect. It is just an infix for getting an element of a list.
There is no way to get the index of x like this in Haskell since the x object doesn't keep track of where it is.
To fix this we can make a list of objects that do keep track of where they were. This can be achieved with zip.
zip [0..] graph
This creates a list of tuples each containing their index and the value in graph.
So you can write your list comprehensions as
[ x | (index, x) <- zip [0..] graph, index > 5, index < 10 ]
Now this is not going to be terribly fast since it still needs to go through every element of the list despite the fact that we know no element after the 11th will be used. For speed we would want to use a combination of take and drop.
drop 5 (take 10 graph)
However if we wanted to do some other selections (e.g. all even indexes), we can still go back to the list comprehension.
In this case, you could drop 5 <&> take 4. As in drop 5 x & take 4. Drop skips the first few elements and take leaves out all but the first few left after the drop.

How to add the elements of a list to a hashtable?

I'm trying to add elements to my hashtable by using a list.
I have a node type like the following :
type position = float * float
type node = position
I wrongfully assumed and started to write my function as if I could apply the same method of recursively building a normal list, but I don't know where to put my recursive call now.
This is what I've tried so far :
let init_dist nodes source =
let hshNodes = Hashtbl.create (List.length nodes) + 5 in
let rec init_dist_aux nodes hashtable source =
match nodes with
| [] -> hashtable
| x::tl > if x = source then Hashtbl.add hashtable (x,0.)
else Hashtbl.add hashtable (x,max_float)
The nodes argument is a list of node, source is a node.
I have no error output because I didn't run this due to the fact that it just couldn't work.
My goal is to be able to write a function that allows me to add bindings to my hashtbl using a list of node.
Thanks.
Your approach seems fine. I don't see any recursive call to init_dist_aux, so it will stop after adding the first element. Also it will generate a type error since one branch of your match returns a hash table and the other returns unit (()).
Adding the recursive call should fix both of these problems.
Update
You have this right now:
if x = source then
Hashtbl.add hashtable (x,0.)
else
Hashtbl.add hashtable (x,max_float)
What you want to have is this:
if x = source then
Hashtbl.add hashtable x 0.
else
Hashtbl.add hashtable x max_float;
init_dist_aux tl hashtable source
With this change, your init_dist_aux function already returns a hash table. There's nothing special to do to get this to happen.
But note that I don't see a call to init_dist_aux anywhere. You definitely need to call it to get things to work :-)
(As a side comment, if the code for init_dist_aux isn't fairly obvious to you you might need to spend a little more time thinking about recursion. Just a humble observation.)

Adding an element to a list and then reverse it

I'm learning Haskell, and attempting to understand lists.
From researching, to add an element to a list, you would normally do:
let numbers = [4,8,15,16,23,42]
numbers ++ [56]
but to quote this answer:
If you need to do this, there is usually a better way to structure
your algorithm. For example, you can build your list in reverse order
(adding elements at the beginning) and only call reverse at the end.
Code:
let numbers = [23,43,56]
let newNumbers = 69:numbers
reverse newNumbers
Output:
[56,43,23,69]
Question:
Is the code I've written correct according to the quoted answer?
I want to understand the terminology a little better, can I say I'm adding elements to the head of the list? From my understanding, every new element would be the first element, and the value returned when I write head newNumbers.
You need to distinguish between the linked list data structure and whatever list-like data type you are implementing with the linked list. You can do exactly two things to modify a linked list: prepend a new head to the list, and remove the current head (if the linked list isn't empty).
The use case the quote talks about is common for a queue data type: you can add to one end and remove from the other end. You can implement this using two linked lists, by adding new elements to one list and removing elements from the other. The implementation of the queue takes care of reversing as necessary to ensure that you never remove an item before every other item inserted previously is removed.
data Queue a = Queue [a] [a]
-- Put new elements on the incoming list.
addToQueue :: a -> Queue a -> Queue a
addToQueue x (Queue incoming outgoing) = Queue (x:incoming) outgoing
-- Take elements from the outgoing list, whose elements are stored
-- in the reverse order that they were added to the incoming list
-- previously.
removeFromQueue :: Queue a -> (a, Queue a)
removeFromQueue (Queue [] []) = error "Cannot remove from empty queue"
removeFromQueue (Queue incoming (x:xs)) = (x, Queue incoming xs)
removeFromQueue (Queue incoming []) = removeFromQueue (Queue [] (reverse incoming))
(We're not concerned with good ways to deal with removing from an empty queue here; just call it an error and leave it at that.)
Adding to the incoming list and removing from the outgoing list is easy. The tricky part is how and when we transfer items from the incoming list to the outgoing list. We only do so when the outgoing list is empty, and when it is, we transfer the entire incoming list at once, reversing it in the process. In other words, we're building up the incoming list in reverse,
but only ever reverse it when necessary, not after each and every single item is added.
Amortized analysis can be used to show that although reverse could be slow, it is balanced by the number of fast operations that precede and can follow it.

Elixir: Find middle item in list

I'm trying to learn Elixir. In most other languages i've battled with, this would be an easy task.
However, i can't seem to figure out how to access a list item by index in Elixir, which i need for finding the median item in my list. Any clarification would be greatly appreciated!
You will want to look into Enum.at/3.
a = [1,2,3,4,5]
middle_index = a |> length() |> div(2)
Enum.at(a, middle_index)
Note: This is expensive as it needs to traverse the entire list to find the length of the list, and then traverse halfway through the list to find what the actual element is. Generally speaking, if you need random access to an item in a list, you should be looking for a different data structure.
This is how I would do it:
Enum.at(x, div(length(x), 2))
Enum.at/3 retrieves the value at a particular index of an enumerable. div/2 is the equivalent of the Python 2.x / integer division.

Adding improper tail to given Erlang list

How do I add an improper tail (e.g. |<<>>) to a proper Erlang list "Parent" with an arbitrary number of elements? I need this to create a range scan upper limit value for matchspecs on a MNESIA table where list keys represent object hierarchy.
To my understanding (inspired by the sext project) any children of a parent key Parent=[T1,T2,T3] (T1,T2,T2 are arbitrary Erlang Terms) can be found with matchspecs asking for:
Child > [T1,T2,T3] and Child < [T1,T2,T3|<<>>]
Given only Parent as a whole, how do I calculate the upper value?
To get the improper list you're looking for, just append the empty binary <<>> to the list:
Parent ++ <<>>.
For example, if Parent is [t1,t2,t3]:
1> Parent = [t1,t2,t3].
[t1,t2,t3]
2> Parent ++ <<>>.
[t1,t2,t3|<<>>]