Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > LISP > Сортировка вставками в бинарном дереве


Автор: ImSassy 16.9.2009, 23:35
Ребят, помогите, пожалуйста, с задачей по Лиспу:
реализовать алгоритм сортировки вставками в бинарном дереве (без сбалансировки)
Что-то у меня вобще никак лисп не идёт((((
Буду очень благодарна

Автор: VH_ 23.9.2009, 07:29
Для «обыкновенного» списка сортировка вставками выглядит, вероятно, так:
Код
(defun SORT_INSERT (L)
 (cond
  ((null L) nil)
  ((null (cdr L)) L)
  (T (INSERT (car L) (SORT_INSERT (cdr L))))))
(defun INSERT (E L)
 (cond
  ((null L) (cons E nil))
  ((< E (car L)) (cons E L))
  (T (cons (car L) (INSERT E (cdr L))))))

Как устроено Ваше бинарное дерево?

Автор: ImSassy 23.9.2009, 17:52
Это лаба, и, впринципе, о каких-то усобых условиях для дерева ничего не оговаривается... Спасибо за помощь)))

Автор: VH_ 23.9.2009, 19:59
Вы можете словесно изложить алгоритм "сортировки вставками" именно "в бинарном дереве" (либо дать ссылку на такое описание)?

Автор: ImSassy 23.9.2009, 20:23
Так вот в том-то и дело, что гугл даже в теории такого не знает, я уточню в универе и отпишу, а то понятно только то, что ничего не понятно

Автор: ImSassy 23.9.2009, 23:09
В общем, вводим список, а потом по нему проходим - на каждом шаге элемент вставляем в дерево, начиная с корня, дальше - если следующий элемент больше, чем элемент в корне, идём на правую ветку, иначе - в левую, и так до листа, а тудо вставляем данный элемент. И дальше нужно вывести уже отсортированный список через отдельную функцию

Автор: lonli 26.9.2009, 11:42
Если ещё актуально, могу сходу набросать структуру дерева и функцию вставки.
Структура такая: каждый "элемент" (я не знаком с терминологией) - cons-ячейка, где car часть - собственно значение.
cdr часть cons-ячейка, гда car содержит левую, а cdr правую ветки, если веток нет, то соотв. части равны nil.

Код

(defun insert-foo (tree val)
  (if tree ; на передали древо или 
      (let ((tree-val (car tree)) ; значение в корне
        (new-tree (cdr tree))) ; собственно оставшееся дерево
    (if (< val tree-val) ; идём направо или налево ?
        ;; налево
        (if (car new-tree) ; проверка, а есть ли уже левая ветка, или там пока пусто
        ;; ветка есть
        (insert-foo (car new-tree) val) ; для наглядности используем рекурсию
        ;; ветки нет. создаём.
        (setf (car new-tree) (cons val (cons nil nil))))
        ;; направо
        (if (cdr new-tree) ; проверка, а есть ли уже правая ветка, или там пока пусто
        ;; ветка есть
        (insert-foo (cdr new-tree) val) ; для наглядности используем рекурсию
        ;; ветки нет. создаём.
        (setf (cdr new-tree) (cons val (cons nil nil)))))))


Для первого элемента сортируемого списка корень дерева создаём вручную.
Код

(let ((tree (cons (car list) (cons nil nil))))
  (dolist (i (cdr list)) ; (cdr list) == (rest list) потому, что первый элемент уже обработан
    (insert-foo tree i))
  развёртываем дерево в новый список)


Правильность работы не проверял. 

P.S. (cons foo nil) эквивалентно (list foo), но так как мы рассматриваем tree не как вложенный список, для понятности я писал cons.
PPS есть более "красивый"  вариант в функциональной парадигме (без setf, каждый раз insert-foo создаёт новую ячейку), но он гораздо менее понятен.

Автор: VH_ 29.9.2009, 17:14
Код
(defun SORT (L)
 (if L
  (INSERT (car L) (SORT (cdr L)))))

Код
(defun INSERT (elem tree)
 (if tree
  (apply
  '(lambda (root left right)
    (if (< elem root)
     (list root (INSERT elem left) right)
     (list root left (INSERT elem right))))
   tree)
  (list elem nil nil)))

Разве это может быть «гораздо менее понятно»?

Автор: VH_ 30.9.2009, 12:32
Развертывание дерева в линейный список:
Код
(defun LINE (tree)
 (if tree
  (apply
  '(lambda (root left right)
    (append
     (LINE left) (list root) (LINE right)))
   tree)))


Автор: ImSassy 1.11.2009, 15:28
Спасибо Вам огромное за помощь)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)