I am new to scheme and I need a help. How to find a parent of the element in the tree?
;; returns left subtree of node
(define (left node)
(if (null? node) '()
(cadr node)))
;; returns right subtree of node
(define (right node)
(if (null? node) '()
(caddr node)))
I think it should be like that:
(define (parent element tree)
(cond
((null? tree) )
(car tree)
((< val (car tree)) (parent val (left tree))) ;
((> val (car tree)) (parent val (right tree)));
)
)
Add an extra argument to parent
(define (parent element parent-of-tree tree)
...)
The root element has no parent, so call parent like this:
(parent element #f tree)
When you go deeper in the tree, pass the parent in parent-of-tree.
For example the (< val (car tree)) becomes:
((< val (car tree)) (parent val tree (left tree)))
Related
I'm trying to implement an AVL tree in Scheme. My approach to this task was to initially make an initial tree representation and progressively implement AVL properties after completing so. I've tried to implement it as such and it won't work because I keep getting an undefined identifier error for both my rotation and deletion functions. Could anyone help me decipher this or aid in my implementation of an AVL tree? My code is as follows:
(define (make-tree value left right)
(list value left right))
(define (key tree)
(car tree))
(define (left-tree tree)
(cadr tree))
(define (right-tree tree)
(caddr tree))
(define (make-leaf key) (list key '() '()))
(define (empty-tree) '())
(define (isEmpty? tree)
(null? tree))
(define (size tree)
(cond ((isEmpty? tree) 0)
(else (+ 1 (size (left-tree tree))
(size (right-tree tree))))))
(define (height tree)
(cond ((isEmpty? tree) 0)
(else (+ 1 (max (height (right-tree tree))
(height (left-tree tree)))))))
(define (isValid? val left-tree right-tree)
(and (>= val left-tree)
(< val right-tree)))
(define (isLeaf? tree)
(and (isEmpty? (left-tree tree))
(isEmpty? (right-tree tree))))
(define (delete tree val)
(cond ((isEmpty? tree) (empty-tree))
((= val (key tree)) (remove-root tree))
((< val (key tree))
(make-tree (key tree) (delete (left tree) val) (right tree)))
((> val (val tree)) (make-tree (key tree)
(right tree)
(delete (right tree) val)))))
(define (delete-root tree)
(cond ((isLeaf? tree) (empty-tree))
; If one child exists then return that child and its descendants
((isEmpty? (left tree)) (right tree))
((isEmpty? (right tree)) (left tree))
;Two children exists
(else (let* ((new-value (key (leftmost-child (right tree))))
(new-right-tree (delete (right tree) new-value)))
(make-tree new-value (left-tree tree) new-right-tree)))))
;Inserts a value into a tree
;Does not obey AVL properties
(define (insert value tree)
(cond ((isEmpty? tree) (list value () ()))
((= value (key tree)) tree) ;Value is in tree
((< value (key tree))
(list (key tree) (insert value (left-tree tree)) (right-tree tree)))
(else (list (key tree) (left-tree tree) (insert value (right-tree tree))))))
;Returns the leftmost-child of an input tree
(define (leftmost-child tree)
(cond ((isEmpty? tree) empty-tree)
((isEmpty? (left-tree tree)) tree)
(else (leftmost-child (left-tree tree)))))
;Makes a tree from an input list
(define (list-to-tree list-in)
(define (list-to-tree-helper list-in tree)
(cond ((null? list-in) tree)
(else (list-to-tree-helper (cdr list-in)
(insert (car list-in) tree)))))
(list-to-tree-helper list-in ()))
;Checks if the heights of the left and right subtrees are equal
(define (isBalanced? tree)
(cond ((isEmpty? tree) #t)
(else (and (= (height (left-tree tree))
(height (right-tree tree)))
(= (isBalanced? (left-tree tree))
(isBalanced? (right-tree tree)))))))
;left rotation
(define (rotate-left tree)
(cond ((isEmpty? tree) tree)
(else (make-tree (key tree)
(left (left tree))
(make-tree (key tree) (right (left tree) (right tree))))))
;right rotation
(define (rotate-right tree)
(cond ((isEmpty? tree) tree)
(else (make-tree (key (right tree))
(make-tree (key tree) (left tree) (left (right tree)))
(right (right tree))))))
;right-left
(define (rotate-right-left tree)
(cond ((isEmpty? tree) tree)
(else (make-tree (key (left (right tree)))
(make-tree (key tree) (left tree) (left (left (right tree))))
(make-tree (key (right tree)) (right (left (right tree))) (right (right tree)))))))
;left-right
(define (rotate-left-right tree)
(cond ((isEmpty? tree) tree)
(else (make-tree (key (right (left tree)))
(make-tree (key (left tree)) (left (left tree)) (left (right (left tree))))
(make-tree (key tree) (right (right (left tree))) (right tree))))))
;Avl-tree factor
(define (avl-factor tree)
(- (height (left tree)) (height (right tree))))
;Balance tree according to avl tree properties:
;|h_l - h_r| = -2 < h < 2
(define (avl-balance tree)
(let ((factor (avl-factor tree)))
(cond ((= factor -2)
;left tree is bigger
(cond ((> (factor (left tree)) 0) (rotate-left-right tree))
(else (rotate-left tree))))
((= factor 2)
;right tree is bigger
(cond ((< (factor (right tree)) 0) (rotate-right-left tree))
(else (rotate-right tree))))
(else tree))))
;(list-to-tree '(4 2 6 8 1 7))
;(define my-tree (make-tree 5 () () ))
(define my-tree (list-to-tree '(4 2 6 8 1 7)))
(isEmpty? my-tree)
(size my-tree)
(height my-tree)
(isLeaf? my-tree)
;Does not work
;(delete 6 my-tree)
;(delete 4 my-tree)
;(delete 7 my-tree)
;does not work
;(delete-root my-tree)
(leftmost-child my-tree)
(rotate-right my-tree)
i'm attempting to count duplicate in a tree. i'm attaching a picture for a better illustration. I'm on the wrong track i have no where to go.
Here is what i did
(define (arbre-insere valeur arbre)
(cond ((null? arbre) (list (cons valeur 1) '() '()))
((< valeur(car arbre))
(list (cons (car arbre) count)
(arbre-insere valeur (cadr arbre))
(caddr arbre)))
(> valeur(car arbre) (list cons ((car arbre) count) (cadr arbre)
(arbre-insere valeur (caddr arbre) )))
(else
)
))][1]
Here is a sketch, where ... and stuff in <...> is meant to be filled out by you.
(define leaf '())
; leaf? : tree -> boolean
; return #t if the tree is a leaf,
; #f otherwise
(define (leaf? tree)
(null? leaf?))
; value : tree -> element
; return the root element of the tree
(define (value tree)
...)
; count : tree -> integer
; return the count of the root element of tree
(define (count tree)
...)
; left : tree -> tree
; return the left subtree of tree
(define (left tree)
...)
; right : tree -> tree
; return the right subtree of tree
(define (right tree)
...)
; make-node : value integer tree tree
; construct tree from a value and count,
; left is a tree whose elements are smaller than value
; right is a tree whose elements are greater than value
(define (make-node value count left right)
(list left (cons value count) right))
; tree-insert : value tree -> tree
(define (tree-insert v t)
(cond
[(leaf? t) (make-tree v 1 leaf leaf)]
[(= v (value t)) (make-tree v <old-count+1> (left t) (right t))]
[(< v (value t)) (make-tree v (make-node (value t) (count t)
(insert-tree v (left t)) r))]
[(> v (value t)) <???>]
[else (error 'tree-insert "an unexpected error occurred")]))
;; A [BT X] is one of
;; - 'leaf
;; - (make-node X [BT X] [BT X])
(define-struct node (val left right))
;; interpretation: represents a node with a value
;; a left and right subtree
(define (tree-sum tree)
(cond
[(symbol=? tree 'leaf) ...] ;; the value remains same
[(node? tree)
(+ (tree-sum (node-val tree))
(tree-sum (node-left tree))
(tree-sum (node-right tree)))]))
not quite sure if i'm on the right track.
Normally, A pair tree is either
a leaf (not a pair), or
a pair, whose car and cdr values are pair-trees.
recursive summing procedure will have to deal with these two cases:
a numbers, i.e., leaves of a tree of numbers, and
pairs, in which case it should sum the left and right subtrees, and add those sums together.
Therefore,
(define (pair-tree-sum pair-tree)
(cond
[(number? pair-tree)
pair-tree]
[else
(+ (pair-tree-sum (car pair-tree))
(pair-tree-sum (cdr pair-tree)))]))
You can split the function into two parts - one that converts the tree into a list of numbers, and another that just uses foldl with that list, and foldl has the advantage of automatically doing the summation as an accumulator.
(define (tree->list tree)
(if (pair? tree)
(append (tree->list (car tree))
(tree->list (cdr tree)))
(list tree)))
(define (tree-sum tree)
(foldl + 0 (tree->list tree)))
You first need to check if the tree is empty, then if its not a list, else you call the function sum to the car of the list, and add to the cdr of the list.
(define (sum tree)
(cond [(empty? tree) 0]
[(not (list? tree)) (if (number? tree) tree 0)]
[else (+ (sum (first tree)) (sum (rest tree)))]))
Could you please help me with a function, I need to find the predecessor in the tree, but it returns an empty list, how to return the predecessor without using "set!"
(define (predecessor val tree)
(cond ((null? tree) (node tree)) ; If the set is null result is predecessor
((> val (node tree)) (predecessor val (right-branch tree))); if val is greater
((< val (node tree)) (predecessor val (left-branch tree))))) ; if val is lesser
(define (node tree)
(car tree))
(define (left-branch tree)
(cadr tree))
(define (right-branch tree)
(caddr tree)))
It returns empty list because of the base case of your recursive procedure.
The only time it exits is when (null? tree) is true and tree is what you return there.
How about this instead (untested)?
(define (predecessor tree val)
(define (helper sub-tree parent)
(cond (((= (node sub-tree) val) parent)
((< (node sub-tree) val) (helper (right-branch sub-tree) sub-tree))
(else (helper (left-branch sub-tree) sub-tree)))))
(helper tree '()))
It maintains the parent along with the sub-tree through each level of recursion.
I am a noob at Scheme. I have a binary search tree. The format of a node is a list of three elements, the first being the value at the node, the second being the left child node, and the third being the right child node. The "make" function creates an empty tree that looks like this: ( () () () ). I am able to create the tree, insert values, and find if a certain value exists in the tree. My problem comes when I try to write a function that returns the tree as an ordered list. Insert and Make functions:
;Inserts a number into the tree
(define (insert t x)
(cond ((null? (car t))
(list x (make) (make)))
((< x (car t))
(list (car t) (insert (cadr t) x) (caddr t)))
((> x (car t))
(list (car t) (cadr t) (insert (caddr t) x) ))
)
)
;Makes a new empty tree
(define (make)
(list (list) (list) (list))
)
Those works fine. Here is my as-list:
;Gives list of all numbers
(define (as-list t)
(cond
(
(null? (car t) )
(list)
)
(
#t
(append (as-list (cadr t)) (as-list (car t)) (as-list (caddr t)))
)
)
)
Running this, I get a contract violation, saying it expected "mpair?". I do not believe this is a logic error on my part, but it may be. Is this another parentheses problem?
Thank you for your time!
Your recursion should be
(append (as-list (cadr t)) (list (car t)) (as-list (caddr t)))
You only want to call as-list on trees, and the car of your t is not a tree.