繁体   English   中英

二叉搜索树方案

[英]Binary Search Tree Scheme

我和我的朋友当前正在在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

由于这听起来像是一项任务,所以我不想提供所需的确切代码,但是我将展示两个可以用来代替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)

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM