二进制搜索树方案

时间:2013-09-26 23:20:13

标签: insert tree scheme binary-search-tree subtree

我和我的朋友目前正致力于在Scheme中创建二进制搜索树。我们无法保存我们插入的内容。我的教授说我们要用套车! (cdr(左边的子树以某种方式,但我不知道究竟要把它放在哪里。我们应该使用set-car!(cddr(对于正确的子树也是。

到目前为止,我们已经完成了所有这些,但我们只需要帮助它就可以保存插入的节点。

代码:

(define make-empty-BST '())

;create function to see if BST is empty
(define (emptyBST? BST) (null? BST))

;make non-empty BST with explicit list implementation
(define (make-BST root left-subtree right-subtree)  
  (list root left-subtree right-subtree))

;helper get root function
(define (getRoot BST) (car BST))

;helper get left subtree function
(define (getLeftsubTree BST) (cadr BST))   ;(car (cdr tr))

;helper get right subtree function
(define (getRightsubTree BST) (caddr BST))  ;(car (cdr (cdr tr)))

;Checks to see if a leaf is empty
(define (emptyleaf? BST) (and (null? (getLeftsubTree BST)) (null? (getRightsubTree BST))))

;inserts an item into the BST
(define (BST-insert BST item)
  (cond
    ((emptyBST? BST) ;if empty, create a new root with given item - use empty lists for left and right subtrees
     (make-BST item make-empty-BST make-empty-BST))
    ((< item (getRoot BST)) ;if item less than root, add to left subtree
     (make-BST (getRoot BST)
               (BST-insert (getLeftsubTree BST) item) ;recursion
               (getRightsubTree BST)))                                     
    ((> item (getRoot BST))                                         
     (make-BST (getRoot BST)
           (getLeftsubTree BST)
           (BST-insert (getRightsubTree BST) item)))
    (else BST)))  ; it's already in BST, do nothing

2 个答案:

答案 0 :(得分:0)

由于这听起来像是一个赋值,我不想提供你需要的确切代码,但我会展示两个可以说是替换list的第n个元素的函数。第一个类似于你的,因为它返回一个新列表,不会修改输入列表。第二个将修改输入列表。

(define (replace-nth n element list)
  ;; return a new list like list, but whose 
  ;; nth element is element
  (if (= n 0)
      (cons element (cdr list))
      (cons (car list) (replace-nth (- n 1) element (cdr list)))))

(let ((l (list 1 2 3 4 5 6)))
  (display (replace-nth 3 'x l)) ; prints (1 2 3 x 5 6)
  (display l))                   ; prints (1 2 3 4 5 6)

第一个返回一个新列表,但不修改输入列表。它使用cons创建一个新列表,应用于旧列表的一部分和一些新值。这与您通过创建具有新值的新树插入时所执行的操作类似。你传入的树将没有它,但树将会。

(define (set-nth! n element list)
  ;; set the nth element of list to be element
  (if (= n 0)
     (set-car! list element)
     (set-nth! (- n 1) element (cdr list))))

(let ((l (list 1 2 3 4 5 6)))
  (display (set-nth! 4 'x l)) ; prints #<void>
  (display l))                ; prints (1 2 3 4 x 6)

第二个修改传递给它的列表。它的返回值并不那么重要,因为传递给它的结构实际上被修改了。这更像是您想要对插入函数执行的操作。您需要递归,直到到达树中的正确节点,并将其左或右子节点设置为仅包含新元素的新树。

答案 1 :(得分:0)

您提供了“获取”程序,为什么不首先提供“设置”程序?这样做有助于完成“树/节点抽象”,并为您提供了一组基本功能,可以尝试在“插入”过程中使用。

(define (setLeftsubTree BST left) 
  (set-car! (cdr BST) left))

(define (setRightsubTree BST right) 
  (set-car! (cddr BST) right))

现在,在您的insert代码中,当您想要“向左”但没有左侧时,请使用新创建的叶节点调用setLeftsubTree。