我首先需要提一下,我对Scheme很新,因此,下面的问题可能没什么意义。
在学校,我们定义了代数数据类型,它通常有一个无效的构造函数和一些内部/外部的构造函数。
在这种特殊情况下,我有兴趣制作一个BTree
二叉树类型(可能在未来的迭代中平衡),我想要像this这样的Haskell如何处理构造函数。我之前已经看过如何在Scheme here中实现树,但这是不我想要的。
我不想只是围绕列表做一个包装器。我只想写一些类似的东西:
nil: -> BTree
node: BTree x T x BTree -> BTree
然后让知道我的意思:
flattenTree: BTree -> List
然后,我会将其定义为(假设left
,right
,key
已定义:
(define flattenTree
(lambda (t)
(node (flattenTree (left t))
(key t)
(flattenTree (right t)))))
此外,我欢迎有关正确缩进我的计划代码的建议......(并且请加以修改)
答案 0 :(得分:12)
在Scheme中表示二叉树(以及大多数其他数据结构)的规范方法是using lists。 Scheme的一些实现提供了一种用于定义C数据结构样式的新数据类型的工具。在MzScheme(现在的Racket)中,新的二叉树数据类型可以定义为:
(define-struct btree (key left right))
环境将自动为新结构创建构造函数,访问器和更改器程序。
> (define tree (make-btree 1 null null))
> (btree-key tree)
=> 10
> (set-btree-key! tree 10)
在此基础结构之上,您可以定义操作btree的其他过程:
(define (btree-insert! t key)
(if (< key (btree-key t))
(if (null? (btree-left t))
(set-btree-left! t (make-btree key null null))
(btree-insert (btree-left t) key))
(if (null? (btree-right t))
(set-btree-right! t (make-btree key null null))
(btree-insert (btree-right t) key))))
(define (btree-flatten t)
(define (flatten t result)
(if (not (null? t))
(begin
(append result (append (flatten (btree-left t) ())
(list (btree-key t)))
(flatten (btree-right t) ())))
t))
(flatten t ()))
;; test
> (define tree (make-btree 10 null null))
> (btree-insert! tree 12)
> (btree-insert! tree 9)
> (btree-insert! tree 8)
> (btree-insert! tree 15)
> (btree-flatten tree)
=> (8 9 10 12 15)