在二叉树方案中查找列表2

时间:2014-05-23 05:51:03

标签: scheme racket

在Scheme中编写一个函数,接收学生的输入参数列表cedulas(标识),带有学生结构实例的二叉搜索树,并返回学生结构的实例列表,其中标识学生列表在二叉搜索树中。

示例:

这是二叉树

(make-árbol-bin  
(make-estudiante 5 "35889188" "Victor" (make-fecha 10 6 1991) "calle 67 con cra 20" "4444444")  (make-
árbol-bin  
(make-estudiante 2 "6457234" "Manuel" (make-fecha 12 10 1992) "calle 56 con cra 33" "5555555")   (make-árbol-bin 
   (make-estudiante 1 "94252688" "Estela" (make-fecha 20 5 1993) "calle 4 con cra 2" "3333333")    empty    empty)   empty) 
 (make-árbol-bin 
(make-estudiante 7 "34987678" "Juan" (make-fecha 25 3 1995) "calle 34 con cra 12" "6666666")   empty 
 empty) 
)

清单识别

(list "94252688" "94888888") 

它应该返回以下列表:

(list (make-estudiante 1 "94252688" "Estela" (make-fecha 20 5 1993) "calle 4 con cra 2" "3333333") ) 

我这样做但我不能让我返回列表

(define-struct fecha ( dia mes año))

这是学生的结构:

(define-struct estudiante ( codigo id nombre fechanaci direccion telefono))

这是二叉搜索树的结构:

(define-struct arbol-bin( estudiante nod-izq nod-der)) 

这些是搜索树中列表的函数

(define(buscarevd n E)
(cond
[(or(empty? E) (empty? n))false]
[(equal? (first n)(estudiante-id  E)) true]
 [else (buscarevd (rest n) E)]))

(define(buscare n E)
(cond 
 [(empty? E)false]
[(< (car n)(estudiante-id  E)) true]
 [else false]))


(define (member-bt x bt)
 (cond 
 [(empty? bt) false]
[(or(buscarevd x (arbol-bin-estudiante bt))
[else
(member-bt x (arbol-bin-nod-der bt))]))

和这个

(member-bt (list "94252688" "94888888") tree)

返回

true

我能做的就是让我回到列表中。

1 个答案:

答案 0 :(得分:0)

不确定节点之间是否存在某种关系,允许您在此处跳过子树,因此我使用这种方法:

(define (member-bt lst tree)
   (let loop ((tree tree) (res '()))
     (if (null? tree)
         res
         (let* ((node (árbol-bin-estudiante tree))
                (res1 (loop (árbol-bin-nod-der tree) res))
                (res2 (loop (árbol-bin-nod-izq tree) res1)))
           (if (member (estudiante-id node) lst string=?)
               (cons node res2)
               res2)))))

然后

(let ((lst '("94888888" "34987678" "94252688")))
  (let ((res (member-bt lst tree)))
    (values res (map estudiante-nombre res))))
=>
'(#<estudiante> #<estudiante>)
'("Estela" "Juan")

请注意,这只会遍历树一次,但结果列表中学生的顺序与初始列表中的顺序不同。如果需要保留订单,则需要采用不同的方法,例如:

(define (member-bt-ordered lst tree)
  (define (sub e tree)
    (if (null? tree)
        #f
        (let ((node (árbol-bin-estudiante tree)))
          (if (string=? e (estudiante-id node))
              node
              (or (sub e (árbol-bin-nod-der tree))
                  (sub e (árbol-bin-nod-izq tree)))))))
  (filter values (map (lambda (e) (sub e tree)) lst)))

然后

(let ((lst '( "94252688" "94888888" "35889188" "34987678" "6457234")))
  (let ((res (member-bt-ordered lst tree)))
    (values res (map estudiante-nombre res))))
=> 
'(#<estudiante> #<estudiante> #<estudiante> #<estudiante>)
'("Estela" "Victor" "Juan" "Manuel")