练习310."如何设计程序"

时间:2016-03-23 12:45:18

标签: functional-programming racket

我很感激这个练习。 练习310.按顺序设计功能。它使用二叉树并生成树中所有ssn数字的序列,因为它们在查看树形图时从左到右显示。Binary Tree

我的解决方案只是使用节点下方的内容反转每个左侧节点,然后访问右侧节点。尽管序列正确但答案的格式不正确。这是我的代码:

(define-struct no-info [])
(define NONE (make-no-info))

(define-struct node [ssn name left right])
; A BinaryTree (short: BT) is one of:
; – NONE
; – (make-node Number Symbol BT BT)

(define nine9 (make-node 99 "nine9" NONE NONE))
(define one0 (make-node 10 "one0" NONE NONE))
(define two4 (make-node 24 "two4" NONE NONE))
(define one5 (make-node 15 "one5" one0 two4))
(define seven7 (make-node 77 "seven7" NONE NONE))
(define nine5 (make-node 95 "nine5" NONE nine9))
(define two9 (make-node 29 "two9" one5 one8))
(define eight9 (make-node 89 "eight9" seven7 nine5))
(define six3 (make-node 63 "six3" two9 eight9))

; BT -> list
; produce the sequence of ssn numbers from left to right
(define (inorder bt)
  (cond
    [(no-info? bt) '()]
    [else (append (reverse (cons (node-ssn bt) (list (inorder (node-left bt)))))
                  (inorder (node-right bt)))]))

这是我运行(inorder six3)时的结果 (列表(列表(列表'()10)15'()24)29)63(列表'()77)89'()95' ()99)

2 个答案:

答案 0 :(得分:0)

您的代码中有许多奇怪的元素。我希望inorder会返回一个列表,但您仍然要在结果列表(list (inorder (node-left bt))之前将结果打包。这是你得到一堆嵌套列表的唯一原因。

为什么反过来?树中的每个级别最终都会显示一个可以反转的部分列表。然后确定该树是否具有奇数或偶数高度的顺序。

鉴于inorder递归实际返回(10 15 24 29)(77 89 95 99),您执行(append (reverse (cons 63 (list '(10 15 24 29)))) '(10 15 24 29))会导致((10 15 24 29) 63 77 89 95 99),但当然递归不是{0}}真的会返回那些列表,因为它也会创建一个嵌套列表等。

如果您有两个列表和一个元素,并且您需要将一个元素放在中间,则执行(append (10 15 24 29) (list 63) (77 89 95 99))

现在有更好的方法可以做到这一点:

(define (tree->list tree (acc '()))
  (if (tree-null? tree)
      acc
      (tree->list (node-left tree)
                  (cons (node-ssn tree)
                        (tree->list (node-right tree) acc)))))

在应用程序之前,需要计算其参数,因此首先完成(tree->list (node-right tree) acc)。对于您的树,它将为(77 89 95 99),对于具有一个'()且具有两个空节点的节点,它将为ssn。然后ssn被压缩到右侧。然后它将充当左侧递归的累加器。

由于列表是使用cons从结尾开始的,这是程序执行的顺序,所以不需要append``and certainly no need for反向。

答案 1 :(得分:0)

在做了一些阅读后,我想出了这个:

; BT -> list
; produce the sequence of ssn numbers from left to right
(define (inorder bt)
  (cond
    [(no-info? bt) '()]
    [else (append (inorder (node-left bt)) (list (node-ssn bt))
                  (inorder (node-right bt)))]))

一个术语列表不那么优雅。但它运作良好。

或者这个:

; BT -> list
; produce the sequence of ssn numbers from left to right
(define (inorder bt)
  (cond
    [(no-info? bt) '()]
    [else (append (add-to-end (inorder (node-left bt)) (node-ssn bt))
                  (inorder (node-right bt)))]))

(define (add-to-end ls ssn)
  (cond
    [(empty? ls) (cons ssn '())]
    [else (cons (first ls) (add-to-end (rest ls) ssn))]))
相关问题