Графы и деревья - Lisp
Формулировка задачи:
Решение задачи: «Графы и деревья»
- (setq *tree* '(1 (2 (3 (4 nil nil) nil) (5 nil nil)) (6 (7 nil nil) nil))) ;; дерево с картинки
- ==> (1 (2 (3 (4 NIL NIL) NIL) (5 NIL NIL)) (6 (7 NIL NIL) NIL))
- (defun task (tree &optional (m 0)) ;; решение в один проход
- (let* ((v (car tree))
- (left (if (null (cadr tree)) nil (task (cadr tree) m)))
- (right (if (null (caddr tree)) nil (task (caddr tree) m)))
- (ml (if (null left) 0 (cadar left)))
- (mr (if (null right) 0 (cadar right))))
- (cond ((and (null left) (null right)) (list (list (car tree) m) nil nil))
- ((null left) (list (list (car tree) (+ 1 mr)) nil right))
- ((null right) (list (list (car tree) (+ 1 ml)) left nil))
- (t (list (list (car tree) (+ 1 (max ml mr))) left right)))))
- ==> TASK
- (task *tree*)
- ==> ((1 3) ((2 2) ((3 1) ((4 0) NIL NIL) NIL) ((5 0) NIL NIL)) ((6 1) ((7 0) NIL NIL) NIL))
Объяснение кода листинга программы
В этом коде используется язык программирования Lisp. Он решает задачу обхода дерева в один проход. Для этого используется рекурсивная функция task
, которая получает на вход ссылку на корень дерева и возможность установки метки для узлов.
В первой строке кода создается дерево в виде списка. В функции task
происходит обход дерева. Если узел пустой, то рекурсивный вызов функции не происходит и функция возвращает NIL. Если узел не пустой, то рекурсивный вызов функции происходит для левого и правого поддеревьев. Также функция task
сохраняет максимальную метку среди потомков в текущем узле.
В последней строке кода вызывается функция task
для корня дерева. Результатом работы функции является список списков, где наружный список содержит список с корнем дерева и меткой, а внутренние списки содержат списки потомков с их метками.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д