Taking a name and adding it to a binary tree structure - scheme

A node in this tree is a list of three items (name left right), where name is a string, and left and right are the child trees i feel like i have gotten off track is there an easy way to write this with just (define(insert name left right))
(define tree
(lambda (node word)
(cond
((null? node) (make-tree word))
((string=? word (tree-word node))
(set-tree-count! node (+ (tree-count node) 1))
node)
((string<? word (tree-word node))
(set-tree-left! node (tree (tree-left node) word))
node)
(else
(set-tree-right! node (tree (tree-right node) word))
node))))

There's no need to use mutation operations, in general in Scheme we avoid them, in this case in particular is easy (and recommended) to build a new tree as we go. And, why the count? this problem has nothing to do with adding numbers. Also notice that the definition (insert name left right) doesn't make much sense, we want to insert a word starting from a tree's root node; left and right aren't useful as parameters. Let's start again from scratch.
(define (insert node word)
(cond ((null? node) (make-tree word '() '()))
((string=? word (tree-word node)) node)
((string>=? word (tree-word node))
(make-tree (tree-word node)
(tree-left node)
(insert (tree-right node) word)))
(else
(make-tree (tree-word node)
(insert (tree-left node) word)
(tree-right node)))))

Related

scheme consumes BT tree and returns the elements of the tree as a list of strings

You are provided with the following definition for binary tries
(define-struct leaf ())
;; interpretation: represents a leaf on a BT, a node with no children
(define-struct node (word left right))
;; interpretation: represents a node on a BT with a word, a left and a right
;; subtree
;; A BinaryTree (BT) is one of
;; - (make-leaf)
;; - (make-node String BT BT)
Design the program bt->los that consumes a BT tree and returns the elements of the tree as a list of strings. At each node your function should
1.process the left sub tree
2.process the word at this node
3.process the right sub tree
;; bt->los: tree -> los
;; consumes a BT tree and returns the elements of the tree as a list of strings.
(define (bt->los tree)
(cond
[(leaf? tree) ""]
[(node? tree)
(append (bt->los(list (node-left tree)))
(list (node-word tree))
(bt->los (list (node-right tree))))]))
I'm stuck here. Should have missed something. Don't we need recursion here?
Output should be like,
(define bt-abc (make-node "b"
(make-node "a" (make-leaf) (make-leaf))
(make-node "c" (make-leaf) (make-leaf))))
(bt->los bt-abc) (cons "a" (cons "b" (cons "c" empty)))
You are very close here. Just a couple of mistakes.
(define (bt->los tree)
(cond
[(leaf? tree) empty]
[(node? tree)
(append (bt->los (node-left tree))
(list (node-word tree))
(bt->los (node-right tree)))]))
First, you are constructing a list of string. Because it is a list, your base case should be empty. not "". Second, each node, already represents a BT, there is no need to list it. And bt->los returns
a list. With this simple changes, it works as expected for you test case.

Confused about binary search trees (Scheme)

I have a problem that I need to complete:
We can represent a nonempty binary tree by list (root left_subtree
right_subtree) and the empty tree by the empty list. Each binary
search tree with integer labels can be considered representing a set
of integers. Write a function which, given a set of integers S as a
bst and an integer x, returns both the set of all the integers less
than x and that of all the integers greater than x as bst’s. Use a
pair rather than a list to represent the resulting sets.
I'm very new to Scheme. I've built trees using SML as well as prolog, but can't seem to get a hold of what I need to do for Scheme. Could anyone help me out and guide me towards this goal? Is my tree suppose to just look like this?
(list value left right)
Yes, that's one way to define a tree. Just so long as you make a proper ADT and use it consistently, it shouldn't matter after you've defined it.
(define (make-tree root left right)
(list root left right))
(define (right tree)
(caddr tree))
(define (left tree)
(cadr tree))
(define (root tree)
(car tree))
(define (empty-tree? tree)
(null? tree))
(define empty-tree '())
(define (leaf? tree)
(and (empty-tree? (left tree)) (empty-tree? right tree)))
(define (split-tree-at tree x)
(let ((less ...)
(more ...))
(cons less more))
(define (in-tree-below-x tree x) ;;assuming a sorted tree
(cond ((empty-tree? tree) (empty-tree))
((>= (root tree) x)
(in-tree-below (left tree) x))
(else (make-tree (root tree)
(left tree)
(in-tree-below-x (right tree) x)))))

"Rotation of Binary Search Trees" in Scheme

Can anyone help me with my base cases for the rotation of a binary search tree left and right? I tried writing the right rotation function as:
(define (right-rotate T)
(make-tree (car (left T))
(left (left T))
(make-tree(value T) (right (left T)) (right T))))
but this gives me a call to an empty list somewhere. Does this code look correct for a right rotation? Also, what could my base cases be here?
You really need to provide more information, such as what is your representation of a 'tree' and how is a tree missing its 'left' or 'right' child defined and handled.
(define (make-tree value left right)
`(TREE ,value ,left ,right))
(define value cadr)
(define right caddr)
(define left cadddr)
;; How is an 'empty' tree denoted?
(define empty 'EMPTY)
(define (is-empty? tree)
(eq? tree empty))
(define (make-leaf value)
(make-tree value empty empty))
;; Now you have the basis for a solution; here is a start.
(define (right-rotate tree)
(if (is-empty? tree)
empty
(let ((l (left tree)))
(if (is-empty? l)
<something>
(make-tree (value l)
(left l)
(make-tree (value tree) (right l) (right tree)))))))

Binary tree inorder traversal Racket

I am trying to write the algorithm for inorder traversal for a binary tree using RACKET/DR. RACKET
(define (print-records node number)
(cond
[(not (empty? node-left))(print-records (node-left node) number )]
*Do This before moving to next IF clause*
[(not (empty? node-right))(print-records(node-right node) number)]
))
I am trying to follow the following algorithm
InOrder(node)
if node is null return
InOrder(node.left)
Print(node)
InOrder(node.Right)
My problem is that through COND I can execute one expression and it will skip the rest. I tried to add two expressions under one it did not work either e.g ((a)(b)). I also tried to make a helper procedure but that did not work either.
You're using cond in a wrong way. Notice that you have to recursively traverse the left part of the tree, then visit the current node and then recursively traverse the right part of the tree - they're not mutually exclusive alternatives, the three steps need to be performed in precisely that order. Try something like this instead:
(define (print-records node number)
(unless (empty? (node-left node))
(print-records (node-left node) number))
(print (node-value node)) ; replace this line with the actual printing code
(unless (empty? (node-right node))
(print-records (node-right node) number)))
Some explanations:
(unless <condition> <body>) is just shorthand for (cond ((not <condition>) <body>)).
The real work of the traversal is done between the two recursive calls, in this case I wrote (print (node-value node)) as an example, replace that line with the actual printing code for the current node's value.
It's not clear what do you intend to do with the number parameter, as it is it's just being passed around, unused.
Walking a binary-tree is a very general operation. You can make a general procedure and then specialize it with the function to apply to each node.
(define (walker node function)
(unless (empty? node)
(walker (node-left node) function)
(function node)
(walker (node-right node) function)))
Note: it is nice to check for empty? at the beginning of the function.
(define (print-records node number)
(walker node (compose print node-value))) ; ignore number, it seems.
You could also work this as:
(define (walking-with function)
(letrec ((walker (lambda (node)
(unless (empty? node)
(walker (node-left node))
(function node)
(walker (node-right node))))))
walker))
(define print-records-for (walking-with (compose print node-value)))
(print-records-for node)
> ...

Beginner Scheme: Turning Binary Search Trees into lists

I am having trouble with binary search trees and turning them into lists.
(define-struct node (key val left right))
;; A binary search tree (bst) is either
;; empty, or
;; a structure (make-node k v l r), where
;; k is a number (the key),
;; v is a string (the value),
;; l is a bst, where every key in l is less than k, and
;; r is a bst, where every key in r is greater than k.
Can anybody give me hints on how to approach this question?
Create a function bst that consumes a binary search tree and returns a list of all the strings in the value field of the binary search tree nodes and the list must be in descending order based on the key values in the binary search tree.
;;Examples: (bst (make-node 4 "James" (make-node 2 "Kien" empty empty)
;;(make-node 5 "Jack" empty (make-node 11 "Cole" empty empty)))) => (list "Cole" "Jack" "James" "Kien")
Thanks!
Basically, you have to visit all the nodes in the tree using a reverse in-orden traversal (right subtree / value / left subtree), while at the same time creating a list with the answer. Something along these lines:
(define (tree->list tree)
(if (empty? tree)
empty
(append (tree->list (node-right tree))
(cons (node-val tree)
(tree->list (node-left tree))))))
It works as expected:
(define bst
(make-node 4 "James"
(make-node 2 "Kien" empty empty)
(make-node 5 "Jack" empty
(make-node 11 "Cole" empty empty))))
(tree->list bst)
=> (list "Cole" "Jack" "James" "Kien")
(define (tree->list tree)
(if(leaf? tree)
(list (node tree))
(cond((right-branch-only? tree)(append (list(node tree))
(tree->list (right-branch tree))))
((left-branch-only? tree)(append (list(node tree))
(tree->list (left-branch tree))))
(else(append (list (node tree))
(append (tree->list (left-branch tree))
(tree->list (right-branch tree))))))))

Resources