Let's ignore the balancing part of the BST for now.
type 'a bst =
| Leaf
| Node of 'a bst * 'a * 'a bst
A typical insert will look like this:
let rec insert x = function
| Leaf -> Node (Leaf, x, Leaf)
| Node (l, k, r) as n ->
if x = k then n
else if x < k then Node (insert x l, k, r)
else Node (l, k, insert x r)
No doubts, the function insert will create new nodes / make a copy of nodes along the search path.
So my question is is there a way to avoid this copying?
This question comes from Exercise 2.3 of the book Purely Functional Data Structures:
Exercise 2.3 Inserting an existing eleemtn into a binary search tree
copies the entire search path even though the copied nodes are
indistinguishable from the originals. Rewrite insert using exceptions
to avoid this copying. Establish only one handler per insertion rather
than one handler per iteration.
I actually quite don't follow the exercise.
What does it mean by "using exceptions to avoid this copying"?
Why use "exceptions"?
What means "one handler per insertion"?
Note that the copying is avoidable only when inserting an element that's already there! It shouldn't be too hard to see how to do this.
Related
During two weeks I've been doing some simple programs in OCaml. I've noticed that when we are working with a recursive structure T and we want to have the information I on T then depending on the information I we have two types of recursive function.
For simplicity let's assume T is a binary tree. So I'll use the following type :
type 'a tree = Empty | 'a * 'a tree * 'a tree
Now let's say the information I can be calculated from left to right on the binary tree. When I am saying left to right it means that the information I can be calculated from the root to the leaves without getting backward.
To be more clear let's say the information I we want to have is simply "the number of nodes of the binary tree". Then what's nice with this information is that when we get to all leaves then we get I, so we are going left to right in the sense that we begin from the root and expend recursively to the left and right subtree and the end case is when we arrived at the leaves.
So we simply have :
let rec nodes = function
|Empty -> 0 (*it's ok we are done here*)
|Node(_,l,r) -> 1 + nodes l + nodes r
What's very nice is that when the information can be calculated left to right then OCaml's pattern matching is a very strong tool and the information I can be calculated in an easy way.
So more generally we have :
let rec get_information = function
| Empty -> (*here we are done so we return a constant value*)
|Node(_,l,r)-> (*here we apply recusrively the function to the left and right tree*)
Now here comes my problem. Let's say I is an information that can't be calculated from left to right but from right to left. So it means that to get the information I we need to begin from the leaves of the tree and extend recursively to the top and we are done only when we get to the root of the binary tree (so the end case is when we get to the root of the binary tree and not the leaves).
For example, let's say the information I is : "the binary tree has the propriety that for every node the number of nodes in his left subtree is strictly superior to the number of nodes in his right subtree". If we want to solve this in linear time then we need to begin from the leaves and expend recursively to the top (note that I don't necessarily want a solution to the problem).
So to me, it's tricky to write a function that gets the information I when I is a right to left information (it needs to begin from the leaves and extend to the top). On the contrary pattern-matching is perfect when the information is a left to right information.
So my question is how to do when we need to write a function that gets the information I (when I is right to left)? Are there techniques to solve these kind of problems? Is it still possible to use pattern matching in a tricky way in order to get the desired result?
Pattern matching is useful for writing both kinds of function. Higher order functions called folds can also be used.
First, a concrete version. We will want to know whether a tree is left leaning, and if so, how many nodes it has. An int option will represent this nicely, with None indicating any non-left leaning tree.
type 'a tree = Empty | Branch of 'a * 'a tree * 'a tree
let rec tree_info = function
| Empty -> Some 0
| Branch (_, l, r) ->
match tree_info l, tree_info r with
| Some x, Some y when x >= y -> Some (x + y + 1)
| _ -> None
let is_left_leaning tree =
match tree_info tree with
| Some _ -> true
| None -> false
(Note that the condition x >= y is not 'strictly greater than', but this is deliberate; x > y is a poor choice. I'll leave figuring out why as an exercise.)
We can also express this style of function in terms of an operation called a right fold. For this operation one provides a value for each constructor of the datatype being folded over: in each place that constructor occurs, the fold operation will use that value to compute the result of the fold:
let rec foldr empty branch = function
| Empty -> empty
| Branch (x, l, r) ->
branch x (foldr empty branch l) (foldr empty branch r)
Note that the empty value and the Empty constructor have the same arity, and the branch value and the Branch constructor have the same arity, with corresponding argument types. That's characteristic of a right fold.
Given foldr, we can easily define map:
let map f tree =
foldr Empty (fun x l r -> Branch (f x, l, r)) tree
Or of course, 'tree_info':
let tree_info tree =
foldr
(Some 0)
(fun _ l r ->
match l, r with
| Some x, Some y when x >= y -> Some (x + y + 1)
| _ -> None)
tree
This is the alternative to pattern matching on the constructors of tree.
Suppose I have some function that will recurs forever, the simplest one I know is:
f x = f x
How can I write a monad that will modify the behaviour of this function, such that it gives me the value of x, and a continuation that will compute the next step, consisting of the value of x at that step and a continuation...
You could structure this as something like the following (using Haskell for illustrative purposes):
data Steps a where
Done :: a -> Steps a
ToDo :: b -> (b -> Steps a) -> Steps a
with the obvious monad implementation.
However, since b is existentially typed in the ToDo constructor, you won't be able to do much with these intermediate results. In effect, I don't think this will give you any more information than just the plain old partiality monad of
data Partial a = Now a | Later (Partial a)
I am trying to recursively find the nth element in a list in ocaml using the following code.
let rec get_val x n = match x with
[] -> -1
| h::t -> if (n=0) then h else get_val t (n-1)
;;
print_int get_val [1; 2; 3] 1;;
However this code is giving me the error
This function has type int -> unit
It is applied to too many arguments; maybe you forgot a `;'.
Your definition is asking for two separate parameters (i.e., it is curried). But you're passing a pair of parameters (t, n - 1). These aren't the same thing.
To get past this problem, change the recursive call to get_val t (n - 1).
You might consider raising the Not_found exception when the list is too short. That way your code will work for lists of all types.
Update
Now the error is in the line where you test your function. You need parentheses there as well.
(You shouldn't keep changing your code. People who come to this page later won't be able to follow the questions and answers.)
My tree type is
type 'a tree = Tree of 'a * 'a tree list;;
How can I get the mirror image of a tree like this? For me is confusing having a list of children, because I do not know how to get individually to each child and do the recursion whitout losing the parent's track, any idea?
EDITED:
I have kept trying and I think I got the solution:
let spec arbol =
match arbol with
Tree(a,[])-> Tree(a,[])
| Tree(a,l)-> Tree(a, List.rev (
let rec aux = function
Tree(a,[])::[]->Tree(a,[])::[]
| Tree(a,[])::l-> [Tree(a,[])]#(aux l)
| Tree(a,t)::[]-> [Tree(a, (List.rev (aux t)))]
| Tree(a,t)::l-> [Tree(a, (List.rev (aux t)))]#(aux l)
in aux l));;
I have tried it with this tree:
let p = Tree(1, [
Tree(2,[]);
Tree(3, [
Tree(6,[]);
Tree(7,[])
]);
Tree(4,[]);
Tree(5,[])
]);;
And I got as result of # spec p;;
-: int tree = Tree (1, [
Tree (5,[]);
Tree (4,[]);
Tree (3,[
Tree(7,[]);
Tree(6,[])]);
Tree (2,[])
])
So I guess my function works as expected. Let me know if it is not correct
If I understand the function you're trying to compute, there is a very simple answer that takes one line of code.
Unfortunately your code introduces so many cases that it's hard to check by eye.
It looks to me like your aux function is intended to calculate the mirror image of a list of trees. However, it doesn't work on an empty list. If you rewrite aux to work on an empty list, you might find that you won't require so many different cases. In particular, you could remove your outermost match and half the cases in your inner match.
In fact, your aux function (if correct) does all the work. If you look at it properly, you could just use aux for everything.
Since you're using List.rev, I assume you could also use List.map. That would be something to look at also.
Update
Trees are inherently recursive structures, so when looking for a tree algorithm, it often helps to imagine how you would use your algorithm recursively. In this case, you could ask yourself how you would put together mirror images of all the subtrees of a tree to make a mirror image of the whole tree.
This is probably a stupid question but, I cant for the love of god figure out what I'm missing here in the theory behind hash tables with chaining.
This is what I understand:
A hash table uses a hash to associate a key to a location where a value is stored. Sometimes a hash will produce the same location for different keys, ie collisions may occur.
In this case we can implement chaining by storing all values with the same location to a linked list at that location.
What I don't understand is this:
When you enter a key and the hash function produces a location at which there is chaining, how does it determine which value in the linked list at that location belongs to that specific key, as opposed to another key involved in the collision?
I realize this is basic theory, but if anyone could point out errors in my reasoning or tell me what I'm missing I would very much appreciate it.
Simple way: maintain a linked list of "hash table entries", which are key/value pairs. Once you get to the bucket, check your query key against all keys in the bucket.
When you enter a key and the hash function produces a location at which there is chaining, how does it determine which value in the linked list at that location belongs to that specific key, as opposed to another key involved in the collision?
You just resort to linear search of the bucket by key.
You may appreciate the following mini hash table implementation written in F#, taken from this blog post:
> let hashtbl xs =
let spine = [|for _ in xs -> ResizeArray()|]
let f k = spine.[k.GetHashCode() % spine.Length]
Seq.iter (fun (k, v) -> (f k).Add (k, v)) xs
fun k -> Seq.pick (fun (k', v) -> if k=k' then Some v else None) (f k);;
val hashtbl : seq<'a * 'b> -> ('a -> 'b) when 'a : equality
This hashtbl function takes an association sequence xs of key-value pairs, builds a hash table represented as a spine array of ResizeArray buckets and returns a lambda function that finds the appropriate bucket and does a linear search in it for the given key k. The linear search is performed using the Seq.pick function.