Tree 利用scheme建立顺序遍历树和打印节点

Tree 利用scheme建立顺序遍历树和打印节点,tree,scheme,binary-tree,racket,mit-scheme,Tree,Scheme,Binary Tree,Racket,Mit Scheme,我理解算法,但无法使用scheme获得代码。 我正在建立一个二叉搜索树。节点是一对(键值)。 在java中,代码运行良好: public void inOrder(BinaryNode n) { if (n != null) { inOrder(n.left); System.out.println(n.value); inOrder(n.right); } } 在scheme中,我的起始代码如下: (define empty (

我理解算法,但无法使用scheme获得代码。 我正在建立一个二叉搜索树。节点是一对(键值)。 在java中,代码运行良好:

public void inOrder(BinaryNode n) {
    if (n != null) {
        inOrder(n.left);
        System.out.println(n.value);
        inOrder(n.right);
    }
}
在scheme中,我的起始代码如下:

(define empty ())

(define empty? null?)

(define (node_key tn) (list-ref tn 0))

(define (node_val tn) (list-ref tn 1))

(define (node_left tn) (list-ref tn 2))

(define (node_right tn) (list-ref tn 3))

(define (tree-node key value left right) (list key value left right))

(define (get-key tn) (node_key tn))

(define (get-val tn) (node_val tn))

(define (get-left tn) (node_left tn))

(define (get-right tn) (node_right tn))

(define (get-pair tn) (list (get-key tn) (get-val tn)))

(define (atom? tn) (and (empty? (get-left tn)) (empty? (get-right tn))))

(define (printInOrder  t)
  (if (not (empty? t))       
      (begin
        (printInOrder (get-left t))
        (get-pair t)
        (printInOrder (get-right t))
        )
      )
  ) 
但是,如果我们测试printInOrder:

(define a (tree-node 3 30 empty empty))

(define b (tree-node 1 10 empty empty))

(define c (tree-node 2 20 b a))

(printInOrder  c)
它应该打印:

1 10
2 20
3 30
但它不起作用,什么也不打印


有人能帮忙处理这件事吗?谢谢。

您编写的代码大致相当于:

public void inOrder(BinaryNode n) {
    if (n != null) {
        preOrder(n.left);
        n.value;
        preOrder(n.left);
    }
}
(…除了Java可能会将裸n.value视为语法错误,因为它没有被用于任何有趣的事情。)


除非表达式的值达到顶级,否则表达式不会自动打印其值。否则,必须显式打印值。您可以使用display和newline来获得System.out.println的效果。如果您使用的是Racket,那么您还必须与之合作。

Alan,对于一个java程序员来说,您的顶级环境中充斥着许多函数。考虑这样的节点对象:

    (define make-node
      (lambda (key value)
        (let ((left '()) (right '()))
          (lambda (m)
            (cond
              ((eq? m 'key) key)
              ((eq? m 'value) value)
              ((eq? m 'left) left)
              ((eq? m 'right) right)
              ((eq? m 'set-left) (lambda (x) (set! left x)))
              ((eq? m 'set-right) (lambda (x) (set! right x)))
              (else (error "Error (make-node): unknown op " m)) )))))
当然,要做成一棵羽翼未丰的树,你需要比这多一点;您希望列表对象至少具有一个insert方法(手动执行此操作意味着您可能会意外地将错误节点放在树中的任意点的“左”或“右”中)。我还将向树对象添加一个list-in-order方法,返回一个键->值对列表,然后您可以对该列表执行任何操作(包括显示它)


我并不是说这是构建树的最佳方式,但它更干净。

现在不是解决风格问题的好时机!:)取决于他或她正在学习的课程的哪一部分(比如SICP),这可能还不是一个合适的时机:他们可能还没有学会如何将闭包作为对象来对待。如果他或她正在使用一个专业的实现,那么应该使用结构或记录来表示节点,而不是列表表示。我假设这是家庭作业,所以这里有一些人为的限制。嗨,谢谢你们!我将对此进行试验。看起来确实干净多了。就像Dyoo所说的,有些函数是固定的,这是家庭作业。但是,我们仍然可以在不改变基本内容(例如,具有键值的节点、过程参数、参数等)的结构的情况下创建自己的结构。此外,我对scheme完全陌生,在scheme学习期间可能会寻求您专业人士的帮助。我非常感谢你们,再次感谢你们。祝你们玩得愉快。这是一种美丽的语言。谢谢你的帮助!我已经纠正了我的代码如下,它的工作!(定义(显示顺序t)(如果(不是(空?t))(开始(显示顺序(向左t))(显示顺序(向右t))(显示顺序(向右t)))