Recursion Lisp程序检查二叉树是否为二叉搜索树

Recursion Lisp程序检查二叉树是否为二叉搜索树,recursion,lisp,binary-tree,common-lisp,binary-search-tree,Recursion,Lisp,Binary Tree,Common Lisp,Binary Search Tree,编写一个Lisp程序来检查二叉树是否是二叉搜索树 节点的左子树的键小于或等于其父节点的键。节点的右子树的键大于其父节点的键 列表可用于表示二叉树的结构,如下所示: ”(8(3(1())(6(4())(7())(10(())(14(13)())),这将返回true 我正在尝试编写一个二进制递归方法,但我是一个初学者,我不知道从这里可以走到哪里 (defun isBST (L) (cond ((null (first L)) t) ((and (not (

编写一个Lisp程序来检查二叉树是否是二叉搜索树

节点的左子树的键小于或等于其父节点的键。节点的右子树的键大于其父节点的键

列表可用于表示二叉树的结构,如下所示:
”(8(3(1())(6(4())(7())(10(())(14(13)()))
,这将返回true

我正在尝试编写一个二进制递归方法,但我是一个初学者,我不知道从这里可以走到哪里

(defun isBST (L)
   (cond 
         ((null (first L)) t)
         ((and (not (null (caadr L)) ) (< (first L) (caadr L)) )  nil)
         ((and (not (null (caaddr L))) (> (car L) (caaddr L)))  nil)
         ((and (not (isBST (cadr L))) (not (isBST (caddr L)))) ))
  )


       
(取消isBST(L)
(续)
((空(第一个L))t)
((和(非(空)(caadr L))(<(第一个L)(caadr L)))无)
((和(非空)(caaddr L))(>(car L)(caaddr L)))无)
(和(不是(isBST(cadr L)))(不是(isBST(cadr L))))
)

你可以用代码表达你的定义,让你的生活更轻松

一个节点被表示为三个元素的列表:键、左子树和右子树

(defun node-key (node)
  (first node))

(defun node-left-subtree (node)
  (second node))

(defun node-right-subtree (node)
  (third node))
要使树成为二叉搜索树,必须满足四个条件,除非两个子树都为空:

  • 左子树必须是二叉搜索树
  • 右子树必须是二叉搜索树
  • 左子树的最大键(如果存在)必须小于根键
  • 右子树的最小键(如果存在)必须大于根键
注意:Lisp中的命名约定是用小写字母书写,单词部分用破折号分隔。谓词,即。E用于获取真值的函数,以
p
结尾。二进制搜索树的谓词可以命名为
bst-p
binary-search-tree-p
。获取bst最大密钥的函数可以称为
bst最大密钥


为了获得BST的最大(最小)键,您只需要在右(左)子树上递归。

您可以用代码表达您的定义,使您的生活更轻松

一个节点被表示为三个元素的列表:键、左子树和右子树

(defun node-key (node)
  (first node))

(defun node-left-subtree (node)
  (second node))

(defun node-right-subtree (node)
  (third node))
要使树成为二叉搜索树,必须满足四个条件,除非两个子树都为空:

  • 左子树必须是二叉搜索树
  • 右子树必须是二叉搜索树
  • 左子树的最大键(如果存在)必须小于根键
  • 右子树的最小键(如果存在)必须大于根键
注意:Lisp中的命名约定是用小写字母书写,单词部分用破折号分隔。谓词,即。E用于获取真值的函数,以
p
结尾。二进制搜索树的谓词可以命名为
bst-p
binary-search-tree-p
。获取bst最大密钥的函数可以称为
bst最大密钥


为了获得BST的最大(最小)密钥,您只需要在右(左)子树上递归。

下面是一个可能对您有所帮助的scheme过程

(define (is-bst l)
  (define (loop node proc)
    (if (null? node)
        #t
        (and (proc (car node))
             (loop (cadr node)
                   (curry > (car node)))
             (loop (caddr node)
                   (curry < (car node))))))
  (loop l (const #t)))
使其中一个节点无效,以确保
是bst
检测到非bst

(is-bst '(8 (3 (1 () ())
               (6 (4 () ())
                  (7 () ())))
            (10 ()
                (2 (13 () ()) ;; 14 changed to 2; invalid tree
                   ()))))

;; #f
要稍微改进一下,请注意,在上面的过程中,我们调用了三次
(car节点)
。使用
let
可以避免这种情况

(define (is-bst l)
  (define (loop node proc)
    (if (null? node)
        #t
        (let ((value (car node)))
          (and (proc value)
               (loop (cadr node)
                     (curry > value))
               (loop (caddr node)
                     (curry < value))))))
  (loop l (const #t)))
现在我们编写
is bst
来检查值是否按升序出现

(define (is-bst l)
  (define (loop x s)
    (if (stream-empty? s)
        #t
        (let ((y (stream-first s)))
          (and (< x y)
               (loop y (stream-rest s))))))
  (loop -inf.0
        (traverse l)))


(is-bst tree)
; #t

(is-bst '(1 (2 () ())
            (3 () ())))
; #f
(定义(是bst l)
(定义(循环x s)
(如果(流为空?s)
#t
(let((y(流优先于s)))
(和(

因为使用了流,所以这些值是惰性的。如果发现早期的
#f
,则停止流的迭代,并完成计算。

以下是一个可能对您有所帮助的方案过程

(define (is-bst l)
  (define (loop node proc)
    (if (null? node)
        #t
        (and (proc (car node))
             (loop (cadr node)
                   (curry > (car node)))
             (loop (caddr node)
                   (curry < (car node))))))
  (loop l (const #t)))
使其中一个节点无效,以确保
是bst
检测到非bst

(is-bst '(8 (3 (1 () ())
               (6 (4 () ())
                  (7 () ())))
            (10 ()
                (2 (13 () ()) ;; 14 changed to 2; invalid tree
                   ()))))

;; #f
要稍微改进一下,请注意,在上面的过程中,我们调用了三次
(car节点)
。使用
let
可以避免这种情况

(define (is-bst l)
  (define (loop node proc)
    (if (null? node)
        #t
        (let ((value (car node)))
          (and (proc value)
               (loop (cadr node)
                     (curry > value))
               (loop (caddr node)
                     (curry < value))))))
  (loop l (const #t)))
现在我们编写
is bst
来检查值是否按升序出现

(define (is-bst l)
  (define (loop x s)
    (if (stream-empty? s)
        #t
        (let ((y (stream-first s)))
          (and (< x y)
               (loop y (stream-rest s))))))
  (loop -inf.0
        (traverse l)))


(is-bst tree)
; #t

(is-bst '(1 (2 () ())
            (3 () ())))
; #f
(定义(是bst l)
(定义(循环x s)
(如果(流为空?s)
#t
(let((y(流优先于s)))
(和(

因为使用了流,所以这些值是惰性的。如果找到早期的
#f
,流的迭代将停止,计算将完成。

(not(null(caadr L))
并不意味着它是叶节点。它可以是节点。您有3种不同类型的值。值、空值和节点。这是什么
(())
在那里做什么?它打破了节点是
()
或一个包含三项的列表:一个值和两个值subtrees@DipakRathod你的编辑不好。你的每一次更改都破坏了帖子。这是一个技术性问题,因此我可以更快地编辑它。请不要在将来对你还没有足够知识的内容进行更改。@Willence下次我会完美地编辑
(not(null(caadr L))
并不意味着它是一个叶节点。它可以是一个节点。你有3种不同类型的值。值、空值和节点。那
(())
在那里做什么?它打破了节点是
()
或一个包含三项的列表:一个值和两个值subtrees@DipakRathod你的编辑很糟糕。你的每一个修改都破坏了帖子。它被批准为技术性修改,所以我可以访问edi