简体   繁体   中英

Different rules for cons arguments?

I'm new in Racket language and I bumped into an issue. I'm now trying to implement Binary Search Tree using cons(list).

This is a simple BST I tried to make:

在此处输入图片说明

For this BST, if I convert this into Racket list, this can be one possibility: '(6, (4, (), ()), (7, (), ())

To produce this format of list, I used this code:

(define x3 (cons 6 (cons (cons 4 (cons null (cons null null)))
                         (cons 7 (cons null (cons null null)))

And for this code, the result is below:

'(6 (4 () ()) 7 () ())

As you see, this is not what I wanted. The second child node 7 () () is not inside the bracket, which means it doesn't exist as an list. It acts as individual 3 elements, not single list. So I changed a bit:

(define x2 (cons 6 (cons (cons (cons 4 (cons null (cons null null))) null)
                         (cons (cons 7 (cons null (cons null null))) null)
                   )
           )
)

And for this 2nd code, the result is as following:

'(6 ((4 () ())) (7 () ()))

And this is not what I wanted either. The first child node ((4 () ())) now is inside and inside the list. So I did the final try, and the code is like this:

(define x3 (cons 6 (cons (cons 4 (cons null (cons null null)))
                         (cons (cons 7 (cons null (cons null null))) null)
                   )
           )
)

And the result looks like this:

'(6 (4 () ()) (7 () ()))

Now it works! The question is, why these things happen? I kind of realized that the rule is different between the last element of list and the other when cons is used, but after all, aren't they same kind of list?

When writing deep list-of-lists using cons , it can be very easy to lose track of where an inner list begins, or where it ends, etc. So if you are writing out a long list by hand, it might be easier to simply use list :

(list 6 (list 4 null null) (list 7 null null))

Otherwise, you can also build your cons list easily by writing it from the inside out. For example, in your BST, there are two leaf nodes with one root parent node. So you can start from the leaf nodes:

(define left   (cons 4 (cons null (cons null null))))
(define right  (cons 7 (cons null (cons null null))))

then the BST becomes:

(cons 6
      (cons left
            (cons right null)))

which is equivalent to:

(cons 6
      (cons (cons 4 (cons null (cons null null)))
            (cons (cons 7 (cons null (cons null null))) null)))

First of all:

cons creates actually a cell, a cons cell. You can append using cons several cons cells to each other.

(cons 'a 'b) ;; (a . b)
(cons 'c (cons 'a 'b)) ;; (c . (a . b)) 

The lisp notation says, ' . ( ' is ' ', so the last example simplifies to:

(c a . b)

What is a list? Such cons cells or chain of cons cells with last element being ' . ()'. In this case, you are allowed to make it invisible.

(cons 'c (cons 'a null)) ;; or 
(cons 'c (cons 'a 'null)) ;; or
(cons 'c (cons 'a '()))   ;; which are the same!
;; in common lisp even (cons 'c (cons 'a ())) in addition

Is thus simplified to:

(c a) ;; actually (c . (a . null))

These syntax simplification rules and the fact that cons takes only exact 2 arguments but you need 3 slots for the binary tree, makes the cons-constructs more complicated than the problem looks at the first sight.

Your BST should be expressed as lists:

(list 6 (list 4 null null) (list 7 null null))

which is already very complicated to express only with conses manually ... (as explained by assefamaru)

As you see, list is an abstraction over the nesting of conses with the innermost cons - cell consing to a null, and more adapted to the simplication rules of the syntax. Thus much more brain-friendly.

But more elegantly, you should use structs (as explained here https://learningtogetolder.wordpress.com/2013/08/14/creating-a-binary-search-tree-in-racket/ ) by defining that each node expects a value and a left and a right node. Thereby, construction errors are made impossible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM