我目前正在尝试编写一个使用DrRacket在球拍中查找值的函数。在一些帮助下,我想出了以下内容。但是我需要有人向我解释cadr
和caddr
之间的区别?同样在DrRacket中我如何创建BST?它与列表相似吗?
(define (find-val bst elt)
(cond ((null? bst) #f)
((< elt (car bst))
(find-val (cadr bst) elt))
((> elt (car bst))
(bst (caddr bst) elt))
((equal? elt (car bst))
#t)))
答案 0 :(得分:3)
对于问题的第一部分,
(cadr x)
相当于:
(car (cdr x))
和
(caddr x)
相当于:
(car (cdr (cdr x)))
您注意到了这种模式吗? d
和c
之间的每个r
都是cdr
的简写,a
和c
之间的每个r
是car
的简写,按从左到右的顺序。
关于问题的第二部分,有一个非常详细的解释,说明如何在书中SICP,标题设置为二叉树§2.3.3部分代表BST >。在那里,您将找到创建和操作树所需的过程。
答案 1 :(得分:0)
在Racket中,我们可以使用 struct 来定义结构化值的形状。例如:
(struct person (name age))
定义了person
结构。它允许我们创建2场结构化值,例如:
(define p1 (person "danny" 33))
(define p2 (person "richie" 31))
我们可以使用其选择器函数访问结构化值的各个字段。
;; p: person -> void
(define (say-hi p)
(printf "hi, my name is ~a, and I am ~a years old\n"
(person-name p)
(person-age p)))
(say-hi p1)
(say-hi p2)
还有其他创建结构化值的方法,例如使用普通列表结构。但对于Racket中的大多数应用程序,最好使用 struct 。以下是几个原因:
访问结构中的字段很快 - 只需一次解除引用。在列表表示中,字段访问涉及遍历列表结构,这有点贵。
struct 选择器中的类型检查可以更快速地检测传递错误类型数据的错误,并生成相应的错误消息。
然后,创建二叉搜索树涉及定义表示树的各个节点的结构。它还需要在构造过程中遵循相当严格的规则,因为节点按照特殊的方式排序,以便比连续列表更快地搜索结构。
算法教科书应该考虑我们可以遵循的一些潜在规则集来创建BST,以保证节点之间的良好平衡。这些包括red-black trees之类的东西,它们可以在如何将值推入树中时保持树结构的特殊规则。没有什么真正的 Racket 具体到它是如何发生的:它只是我们需要遵循的一般要求才能使余额发挥作用。
Matt Might写了一个在Racket中实现的very nice article on red-black trees。