Insert Node into a Tree - Racket - functional-programming

I am trying to add a new node to the tree. The following are my definitions and function type:
(define-struct (Some T)
([value : T]))
(define-type (Option T)
(U 'None (Some T)))
(define-type BST (U 'E Nd))
(define-struct Nd
([root : Integer]
[lsub : BST]
[rsub : BST]))
(: insert : Integer BST -> BST)
;; insert an item into a tree
;; note: do not insert duplicate items
(define (insert n x)
(match x
('E 'E)
((Nd ro ls rs)
(cond
((= (size x) 1) (Nd ro (Nd n 'E 'E) 'E))
(else
(Nd ro ls rs))))))
Insert is the insert that will insert the node into the tree.
The following is the command that I will give:
(insert 10 (Nd 1 (Nd 2 (Nd 4 'E 'E) (Nd 5 'E 'E)) (Nd 3 (Nd 6 'E 'E) (Nd 7 'E 'E))))
And it should insert ten into the tree. However, I am learning independently at home and I have NO idea what to do. Please help. Thank you so much!

You're missing the recursion, and your base case is wrong.
Inserting in an empty tree creates a tree with one node.
Inserting in a non-empty BST has three cases:
If the item is the same as in this node, return the tree unchanged
If the item is smaller than this node, insert in the left subtree
Otherwise, insert in the right subtree
Something like
(define (insert n x)
(match x
('E (Nd n 'E 'E))
((Nd ro ls rs)
(cond
((= n ro) x)
((< n ro) (Nd ro (insert n ls) rs))
(else (Nd ro ls (insert n rs)))))))
The tree you're aiming to insert in isn't a BST though, so this won't work.
Your tree has the following structure:
1
/\
2 3
/\ /\
4 5 6 7
A search tree with those elements would look like this:
4
/\
2 6
/\ /\
1 3 5 7
which is
(Nd 4 (Nd 2 (Nd 1 'E 'E) (Nd 3 'E 'E)) (Nd 6 (Nd 5 'E 'E) (Nd 7 'E 'E)))

Related

Racket rod cutting problem, how to use vectors in recursive functions

I'm trying to figure out why I'm getting the errors expected vector? and expected pair? and if there's a way to have a vector as a variable and access the vector for the rod cutting problem (similar to the knapsack problem).
#lang slideshow
; test input: (cutrod 5 #(0 1 2 3 2 2 6 1 2 3 10))
(define (square) (colorize(rectangle 20 15) "red"))
(define (rodpiece n) (apply hc-append(vector->list (make-vector n (square)))))
(define (cutrod n s)
(rodpiece n)
(cond
((null? s) '())
(else
(let
([cut (car (vector->list s))]
[rods (cdr (vector->list s))])
(cons cut (cutrod (- n (vector-ref s n)) rods))
(cutrod n rods)
n))))
Here's the C++ PrintSolution version I'm using to convert:
void PrintSolution(int n, int s[]){
while(n>0){
printf(“%d ”, s[n]);
n = n ‐ s[n];
}
}
This error happens when I try to convert the vector to a list, it says it expected a vector:
This error happens when I keep the vector as is, it says it expected a pair:
Part of the problem is that (rodpiece) returns a list, rather than a vector. You can solve this easily by changing it to:
(define (rodpiece n)
(make-vector 1
(apply hc-append
(build-list n
(lambda (x)
(square))))))
There's no need to start with a vector, but the goal is to return one.
The next problem is that you are calling (rodpiece) in a location which basically discards the return value. You want something closer to this:
(define (cutrod n s)
(let* ((sn (vector-ref s n))
(rp (rodpiece sn)))
Which determines the size of the rod piece up front, then gets the current rod piece for use shortly afterwards. You then need to check for the base case of the recursion:
(if (or (<= n 0)
(> n (vector-length s)))
rp
Where if n is zero, or is longer than the remaining vector s, you simply return the current rod piece.
The recursion itself accumulates current rod piece with the remaining rod pieces:
(vector-append rp (cutrod (- n sn) s)))))
Putting this all together, you have:
#lang slideshow
(define (square)
(colorize (rectangle 20 20) "red"))
(define (rodpiece n)
(make-vector 1
(apply hc-append
(build-list n
(lambda (x)
(square))))))
(define (cutrod n s)
(let* ((sn (vector-ref s n))
(rp (rodpiece sn)))
(if (or (<= n 0)
(> n (vector-length s)))
rp
(vector-append rp (cutrod (- n sn) s)))))
(define cut-vector #(0 1 2 3 2 2 6 1 2 3 10))
(cutrod 5 cut-vector)
(cutrod 6 cut-vector)
(cutrod 7 cut-vector)
(cutrod 9 cut-vector)
(cutrod 10 cut-vector)

List of Leaves in Racket

I am trying to create a list of leaves of a tree in Racket.
(define-struct (Some T)
([value : T]))
(define-type (Option T)
(U 'None (Some T)))
(define-type BST (U 'E Nd))
(define-struct Nd
([root : Integer]
[lsub : BST]
[rsub : BST]))
(: leaves : BST -> (Listof Integer))
;; return the list of leaves from left to right
;; note: the result must be strictly ascending
(define (leaves x)
(match x
('E '())
((Nd ro 'E 'E) (list ro))
((Nd ro ls rs)
(append (leaves ls) (leaves rs)))))
The above function however does not work. I get a list of all the leaves but its not ascending. Can someone please help?
I am learning to code at home so don't have access to teachers or mentors.

list to tree in typedracket

I am trying to convert a list of integers to a tree.
The following are my function definitions:
(define-struct (Some T)
([value : T]))
(define-type (Option T)
(U 'None (Some T)))
(define-type BST (U 'E Nd))
(define-struct Nd
([root : Integer]
[lsub : BST]
[rsub : BST]))
(: bst-from-list ((Listof Integer) -> BST))
;; build a BST from a list of integers: use foldl to do s
(define (bst-from-list x)
(cond
('() 'E)
((cons hd _) (Nd hd 'E 'E))
(else
(foldl
I am learning from home and have no idea what to do after foldl. Can someone please help me?>
You already have an (: insert : Integer BST -> BST) function.
To build a tree with the elements 1, 2, 3, using insert you could write
(insert 3 (insert 2 (insert 1 'E)))
This is a left fold over (1 2 3) with insert as the function and 'E as the initial value.
A left fold combines the first element with the initial value and then combines the result of that with the second element, and so on.
So all you need is
(: bst-from-list : ((Listof Integer) -> BST))
(define (bst-from-list ls)
(foldl insert 'E ls))

Find Maximum from a Tree

I am trying to find the maximum number from a given tree:
(define-struct (Some T)
([value : T]))
(define-type (Option T)
(U 'None (Some T)))
(define-type BST (U 'E Nd))
(define-struct Nd
([root : Integer]
[lsub : BST]
[rsub : BST]))
(: maxi : BST Integer -> Integer)
(define (maxi x acc)
(match x
('E acc)
((Nd ro ls rs)
(cond
((> ro acc) (maxi ls ro))
(else
(maxi rs acc))))))
The above quote does not work properly when I enter the following:
(maxi (Nd 1 (Nd 2 (Nd 4 (Nd 8 'E 'E) (Nd 9 'E 'E)) (Nd 5 'E 'E)) (Nd 3 (Nd 6 'E 'E) (Nd 7 'E 'E))) 0)
Can someone please help?
Thank you!
So here is your test:
(maxi
(Nd
1
(Nd 2
(Nd 4
(Nd 8 'E 'E)
(Nd 9 'E 'E))
(Nd 5 'E 'E))
(Nd 3
(Nd 6 'E 'E)
(Nd 7 'E 'E)))
0)
And here is what happens:
acc root what to do?
---------------------------------
0 1 go left with acc = root
1 2 idem
2 4 idem
4 8 idem
8 E return 8
If you expect your input trees to satisfy the binary search tree property, stating that values on the left subtree are always greater than root and values of the right subtree are all smaller or equal, then your test tree is a malformed BST, since 9 is greater than 4.
By the way, if you had a BST, where would the maximal value be located?
If however the tree is just a random tree, then you have to compute the maximum of both subtrees and the root value before being able to determine the overall maximal value.
Basically, you want to do:
(tree-max (Nd root left right)) = (max root
(tree-max left)
(tree-max right))
If you want to do it recursively, you will encounter a problem in the base case because you will have to provide a maximal value for an empty leaf node: any value you will pick will make your code incorrect for a tree which contains values strictly below that value. Say you choose zero and compute the max of a tree with only strictly negative numbers, then zero is the wrong answer because it does not appear in the tree (what could you do?).
You can choose to use an accumulator instead of recursion, but in that case you will need two accumuators: the maximum so far and the list of subtrees to visit next. Basically you replace the call stack with a heap-allocated stack.
I can't currently test the following code, but here is a possible implementation:
(define tree-max (tree greatest todo)
(match tree
('E greatest (if (null? todo)
greatest
(tree-max (first rest)
greatest
(rest todo))
((Nd root left right) (tree-max left
(max greatest root)
(cons right todo))))

Constructing tree from symbolic input

I am trying to construct a tree in scheme language , from string input. Following is what i have tried -
(define travsal (lambda (tree)
(cond
((null? tree) '())
(#t (append (travsal (car tree)) (cons (cadr tree)
(travsal (caddr tree))))))))
(define tree1 '(((() 4 ()) 2 (() 5 ())) 1 ((() 6 ()) 3 (() 7 ()))))
(display tree1)
(newline)
(travsal tree1)
As you can see its just iterating the input provided and not doing what actual binary tree should do.
I am struck at the logic as of how to save the tree using nodes and child from symbolic input like - "(((() 4 ()) 2 (() 5 ())) 1 ((() 6 ()) 3 (() 7 ()))))" and then print it out like above function is printing.
Please help out , i was asked this question in an interview and still can't solve it.
What do you mean with "not doing what actual binary tree should do"? . The traversal code is fine, it's doing an in-order traversal of the tree. Fixing some formatting issues:
(define travsal
(lambda (tree)
(cond ((null? tree) '())
(else (append (travsal (car tree))
(cons (cadr tree)
(travsal (caddr tree))))))))
Now, bear in mind that the tree you provided is binary but not sorted:
(define tree1 '(((() 4 ()) 2 (() 5 ())) 1 ((() 6 ()) 3 (() 7 ()))))
If we draw it, it'll look like this:
1
/ \
2 3
/ \ / \
4 5 6 7
Which, after an in-order traversal will correctly yield this result when using the travsal procedure:
(travsal tree1)
=> '(4 2 5 1 6 3 7)

Resources