2009-11-12 7 views
4

I는 다음의 이진 트리 문자 노드 이름은 리스프 (A 2 B 0 C 2 D 0 E 0)의리스트로 표시LISP의 이진 트리의 깊이를 계산 재귀

 
    A 
/\ 
B C 
/\ 
    D E 

을 숫자는 자식 노드의 수입니다 (0이면 none, 1 노드가 1, 2 노드가 2). 루트 노드에서 트리 깊이 (이진 트리 깊이)를 재귀 적으로 발견해야합니다. 저는 Lisp을 처음 사용하기 때문에 구현 방법을 이해할 수 없습니다. 이것은 내가 지금까지 관리 할 수있는 것입니다 :

 
(defun depth (tree) 
    "Returns the depth of the argument tree." 
    (check-type tree list) 
    (if (= (second tree) 0) 
    0 
    (1+ (get-btree-max-depth (cddr tree))))) 

(defun get-btree-max-depth (btree) 
    "Returns the maximum depth 
    of the argument tree." 
    (check-type btree list) 
    (if (= (second btree) 0) 
    0 
    (max (depth (cddr btree)) 
     (get-btree-max-depth (cddr btree))))) 

그러나 제대로 작동하지 않습니다. 유사한 게시물을 탐색했지만 도움이 될만한 유용한 것을 찾지 못했습니다. 누군가가 나에게이 사실을 알 수 있도록 제안을 해 줄 수 있습니까? 고맙습니다!

P. 이것은 내가 대학에서 선물 할 작은 프로젝트의 일부이지만, Lisp을 더 잘 활용할 수있는 자신 만의 방식 (많은 유사한 게시물에 글이 숙제와 관련이 있는지 질문하는 질문이있었습니다). :)

+1

먼저 더 좋은 형식으로 트리를 변환! – Artelius

+2

즉, 트리는 트리 목록이어야합니다. (이진 트리는 2 개 이하의 이진 트리 목록이어야합니다.) 목록에는 목록이 포함될 수 있습니다. 재귀 함수를 작성하려는 경우 재귀 데이터 구조를 사용하는 것이 좋습니다. – Artelius

+1

B 아래에 다른 노드 F가있는 경우 트리가'(A 2 B 1 F 0 C 2 D 0 E 0) '또는'(A 2 B 1 C 2 F 0 D 0 E 0)'으로 표시됩니까? – Svante

답변

2

내가 먼저 나무에 목록을 변환합니다 :

(defun tlist->tree (tlist) 
    "Transforms a tree represented as a kind of plist into a tree. 
    A tree like: 
       A 
      /\ 
      B C 
      //\ 
      F D E 
    would have a tlist representation of (A 2 B 1 F 0 C 2 D 0 E 0). 
    The tree representation would be (A (B (F)) (C (D) (E)))" 
    (let (tree) 
    (push (pop tlist) tree) 
    (dotimes (i (pop tlist)) 
     (multiple-value-bind (subnode rest-tlist) (tlist->tree tlist) 
     (push subnode tree) 
     (setf tlist rest-tlist))) 
    (values (nreverse tree) tlist))) 

당신이 시작하는이 트리 표현으로 시작하지 수 있는지가 궁금합니다.

그런 다음, 트리 표현 트리의 깊이를 찾는 것은 간단한 재귀 한 줄입니다. Artelius의 및 반테의 답변을 사용

0

나는이 문제를 해결하기 위해 관리. 여기에 코드가 있습니다. 아마 도움이 필요한 누군가에게 도움이 될 것입니다.

 
(defun btree-max-depth (btree) 
    "Returns the maximum depth 
    of the binary tree." 
    (check-type btree list) 
    (if (null btree) 
    0 ; the max depth of the members of() 
    (max (depth (first btree)) 
     (btree-max-depth (rest btree))))) 

(defun depth (tree) 
    "Returns the depth of the argument TREE." 
    (if (atom tree) 
    0 ; an atomic tree has a depth of 0 
    (1+ (btree-max-depth tree)))) 

감사합니다. Artelius 및 Svante에게 도움을 요청합니다.

+0

간단한 한 라이너했을'(defun는 깊이 (트리)에 정의되는 깊이를 가정) '(1+ (# 맥스 -1 (mapcar 등등 번호'깊이 (나머지 트리)))에 적용) 최대 가장자리 수. – Svante

+0

어제 내 대답을 다시 생각해야 할까 봐 걱정됩니다. 조건 중 하나는 트리를 설명하는 목록을 한 형식에서 다른 형식으로 변환하는 것이 아니므로 목록을 파싱하고 트리 구조의 깊이를 계산하는 방법을 알지 못하는 출발점으로 돌아 왔습니다. 이진 트리입니다. 어떤 제안이든이 일을하는 방법을 환영하고 크게 감사드립니다. 감사 – crazybyte

3

어떻게 이런 일에 대해? 나무를 변형시키지 않아도됩니다.

(defun depth-rec (tree) 
    (labels ((depth-rec-aux (depth)    ; self-recursive function 
      (if (null tree)     ; no more nodes 
       depth      ; -> return the current depth 
       (let ((n (second tree)))  ; number of subnodes 
       (pop tree) (pop tree)  ; remove the current node 
       (case n 
        (0 (1+ depth))      ; no subnode, 1+depth 
        (1 (depth-rec-aux (1+ depth)))  ; one subnode, its depth+1 
        (2 (max (depth-rec-aux (1+ depth)) ; two subnodes, their max 
          (depth-rec-aux (1+ depth))))))))) 
    (depth-rec-aux 0)))      ; start depth is 0 

또 다른 버전 :

(defun depth-rec (tree &aux (max 0)) 
    (labels ((depth-rec-aux (depth) 
      (when tree 
       (pop tree) 
       (let ((n (pop tree))) 
       (if (zerop n) 
        (setf max (max max (1+ depth))) 
        (loop repeat n do (depth-rec-aux (1+ depth)))))))) 
    (depth-rec-aux 0)) 
    max) 
1

여기에 계속 - 패싱 스타일 하나 :

(defun oddtree-height (oddtree) 
    (suboddtree-height oddtree 
        #'(lambda (h remainder) 
         (if (null remainder) h nil)))) 

(defun suboddtree-height (oddtree c) 
    (max-height-of-suboddtrees (cadr oddtree) 
          0 
          (cddr oddtree) 
          #'(lambda (h remainder) 
           (funcall c (+ h 1) remainder)))) 

(defun max-height-of-suboddtrees (n best oddtree c) 
    (if (= n 0) 
     (funcall c best oddtree) 
    (suboddtree-height oddtree 
         #'(lambda (h remainder) 
          (max-height-of-suboddtrees (- n 1) (max best h) remainder c))))) 
관련 문제