将列表转换为二叉树的Scheme代码无法正常工作,请求排查
排查你的Scheme二叉树插入代码问题
嘿,我一眼就看到问题出在哪了——你的tree-insert函数最后一个条件分支把左右子树的顺序搞反了!
先看你原代码里的这一行:
((> v (value t)) (make-tree (value t) (tree-insert v (right t)) (left t)))
当插入的值v大于当前节点的值时,按照二叉搜索树的规则,我们应该把v插入到当前节点的右子树里,然后构造新节点时,左子树保持原来的左子树不变,右子树换成插入后的结果。但你这里刚好写反了:把插入后的右子树放到了左子节点的位置,把原来的左子树放到了右子节点的位置,这直接导致所有大于当前节点的值都被错误地塞到了左分支,最终树结构完全混乱。
修正后的代码
首先补上你可能已经定义过的树操作辅助函数(如果还没定义的话),然后修正tree-insert的最后一个分支:
; 树的构造与访问函数 (define (make-tree v l r) (list v l r)) (define (value t) (car t)) (define (left t) (cadr t)) (define (right t) (caddr t)) (define (tree-insert v t) (cond ((null? t) (make-tree v '() '())) ((= v (value t)) t) ; 把eq?换成=更适合数值比较,更严谨 ((< v (value t)) (make-tree (value t) (tree-insert v (left t)) (right t))) ((> v (value t)) ; 修正:左子树保留原左子树,右子树是插入后的结果 (make-tree (value t) (left t) (tree-insert v (right t)))) )) (define (insert-list l t) (if (null? l) t (insert-list (cdr l) (tree-insert (car l) t))))
测试结果
现在执行你原来的测试语句:
(insert-list '(5 2 1 3 11 8 6 9 15 17) '())
会得到符合预期的二叉搜索树结构:
(5 (2 (1 () ()) (3 () ())) (11 (8 (6 () ()) (9 () ())) (15 () (17 () ()))))
这个结构完全符合二叉搜索树的规则:每个节点的左子树所有值都小于它,右子树所有值都大于它。
另外补充个小建议:用eq?比较数值虽然在很多Scheme实现里能工作,但=是专门用于数值比较的运算符,替换后能避免一些潜在的类型匹配问题哦。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

