Racket嵌套列表树中插入3的函数错误排查与修复
解决Racket二叉树插入的契约违反问题
错误原因
你遇到的契约违反错误,本质是递归时没有正确提取子树的根节点——你可能直接将子树列表(比如'(3))当作根值来和插入的实数比较,而不是提取列表中的数值(3),导致类型不匹配。
正确实现思路
根据你的二叉树表示规则:
- 非空树格式:
((根节点) 左子树 [右子树])(空右子树可省略,空左子树必须写'()) - 插入规则:≤根节点插左子树,>根节点插右子树
首先定义辅助函数提取树的核心部分,避免重复逻辑:
; 提取树的根节点 (define (tree-root tree) (caar tree)) ; 提取树的左子树 (define (tree-left tree) (cadr tree)) ; 提取树的右子树(无则返回空) (define (tree-right tree) (if (>= (length tree) 3) (caddr tree) '()))
然后实现递归插入函数:
(define (tree-insert x tree) (cond ; 处理空树(初始空树的情况) [(null? tree) `((,x) ())] [else (let ([root (tree-root tree)] [left (tree-left tree)] [right (tree-right tree)]) (cond [(<= x root) ; 插入左子树后重组树 (let ([new-left (tree-insert x left)]) (if (null? right) `((,root) ,new-left) `((,root) ,new-left ,right)))] [else ; 插入右子树后重组树(空右子树省略) (let ([new-right (tree-insert x right)]) (if (null? new-right) `((,root) ,left) `((,root) ,left ,new-right)))))]))
测试验证
运行你的测试用例:
(tree-insert 3 '((8) ((3) (3)) ((12) (10))))
输出:((8) ((3) ((3) (3))) ((12) (10)))(符合预期)(tree-insert 3 '((8) ((3) (3))))
输出:((8) ((3) ((3) (3))))(符合预期)
关键要点
- 必须通过
(caar tree)提取根节点:因为非空树的根是嵌套列表的第二层元素(((root) ...)中的root) - 处理右子树时要兼容“省略空右子树”的规则:原树无右子树时默认取
'(),插入后若右子树仍为空则不添加到新树中 - 左子树必须始终保留,即使为空也要写
'()
内容的提问来源于stack exchange,提问作者JoshLeonthe1st
相关产品推荐
相关产品推荐

