Recursion 球拍树

Recursion 球拍树,recursion,tree,racket,traversal,Recursion,Tree,Racket,Traversal,我的球拍有以下问题 我正在尝试为一个通用树实现树的预序、后序遍历 结构定义为: (define-struct eempty []) (define-struct branch [left value right]) 我不能使用除非/when操作符,只要if和cond。 我真的想不出解决办法。我看过维基百科的伪代码,但由于racket编程模式的原因,它并没有真正起到帮助作用 (define (inorder tree x) (cond [(and (branch? tree) (branch

我的球拍有以下问题

我正在尝试为一个通用树实现树的预序、后序遍历

结构定义为:

(define-struct eempty [])
(define-struct branch [left value right])
我不能使用
除非/when
操作符,只要
if
cond
。 我真的想不出解决办法。我看过维基百科的伪代码,但由于racket编程模式的原因,它并没有真正起到帮助作用

(define (inorder tree x)
  (cond [(and (branch? tree) (branch? (branch-left tree))) (inorder (branch-left tree) x)]
        [(and (branch? tree) (branch? (branch-right tree))) (inorder (branch-right tree) x)]
这是我到目前为止所做的,但在匹配
空的
结构时存在问题

更新:

我试图做的是按顺序或/和后顺序显示/打印节点值

我知道我必须(以某种方式)实施另外两个条件:

(and (branch? tree) (empty? (branch-left tree))) do-something x)
(and (branch? tree) (empty? (branch-right tree))) do-something x)
在做某事时我必须做什么?我想我没有抓住这一点


有什么帮助吗

看来您缺少了“empty”结构的“cond”分支。关于这方面的帮助,您可以参考教科书,特别是与混合自参考数据相关的“模板”步骤。

我们从我们拥有的开始:

#朗球拍
(定义结构为空[]);无字段
(定义结构分支[左值右]);三场
我们可以试着做一些树:

(定义t1(空))
(定义t2(分支t1 7 t1))
现在我们可以试着玩一下:

> t2 #<branch> > (branch-left t2) #<empty> > (branch-left t1) branch-left: contract violation expected: branch? given: #<empty> > (branch? t2) #t > (branch? t1) #f > (empty? t2) #f > (empty? t1) #t > 所以现在我们可以

>(显示值(分支值t2))
7.
没有
字段,只有
分支
执行以下操作:

(定义(按t顺序显示树)
(续)
((空?t)
(显示为空);稍后定义
((分支机构?t)
(按顺序显示分支;稍后定义)
(分支左t)
(分支值t)
(分支右t(()()))
在定义这一点时,我们遵循了类型:我们的树要么是
空的
,要么是
分支
。这就是我们用这两个结构定义来定义它们的方式

剩下的就是完成
display empty
display branch inoder
缺少的定义

但在我们这么做之前,我们还可以

(定义(显示树的前序t)
(续)
((空?t)
(显示为空)
((分支机构?t)
(显示分支预订单)
(分支左t)
(分支值t)
(分支右t(()()))
(定义(显示树后序t)
(续)
((空?t)
(显示为空)
((分支机构?t)
(显示分支机构邮政订单)
(分支左t)
(分支值t)
(分支右t(()()))
那么,
display empty
在做什么呢?它什么也不做:

(定义(显示为空)
#(f)
那么,
按顺序显示分支呢

(定义(按lt val rt顺序显示分支)
根据Wikipedia我敢肯定,它首先显示它的左子树

(按顺序显示树…)
然后它开始显示它的值

(显示值…)
最后显示右侧的子树:

…)
其他两个变体也一样

在完成所有这些之后,您会感觉到通过遵循关注点分离原则进行抽象和概括的冲动。好。我们的
按顺序显示树将几件事情集中在一起:它根据这个或那个顺序的概念遍历一棵树,并对每个节点的值进行处理。所有这些都可以抽象为一个通用过程的参数,比如说,
遍历树


所以你看,这很简单:遵循类型!具体来说,第4.6节描述了如何为使用
其中一个
的数据定义创建模板。第9节,把它放在像树这样的自参考数据的上下文中,这就是我所缺少的。我知道肯定还有两个条件,即(和(树枝?树)(空的?(树枝左树))和(和(树枝?树)(空的?(树枝左树))。但我不明白如果这些条件是真的,我该怎么办。啊!不,你被困在“空的恐惧”中了陷阱。我猜你有一些编程经验,这会给你带来问题。你几乎应该有一个(空?树)分支。但是,为了更好地回答您的问题,也许您可以为您的问题添加更多的上下文。具体来说,您是在尝试进行前序遍历还是后序遍历?我已经用更多的信息更新了我的问题。非常感谢您的帮助!树的数据定义是什么?树始终是分支吗?还是c它可以是
一个eempty或一个分支中的一个(我指的是约翰·克莱门茨(John Clements)回答中提到的教科书上下文中的数据定义。数据定义是设计配方的第一步。)树是一个分支,左右值可以是一个分支或一个eempty。例如:(define tree(make branch)(make branch)(make branch(使分支空2空)4(使分支空5空)10(使分支空12空)15(使分支空18空)非常感谢!这真的帮助了我!