1 / 17

Функциональное программирование

Функциональное программирование. Факультет инноваций и высоких технологий Московский физико-технический институт. Лекция 12. Деревья. Определение. Дерево общего вида типа T – это Элемент типа T с присоединенными к нему 0 и более деревьями типа T Формально – связанный граф без циклов.

kaiya
Télécharger la présentation

Функциональное программирование

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Функциональное программирование Факультет инноваций и высоких технологий Московский физико-технический институт

  2. Лекция 12 Деревья

  3. Определение Дерево общего вида типа T – это • Элемент типа T с присоединенными к нему 0 и более деревьями типа T • Формально – связанный граф без циклов 1 2 3 4 5 6 7

  4. 1 2 3 4 5 6 7 Описание • Лист – это терминальный элемент без поддеревьев • Узел – это элемент, содержащий значение и поддеревья type 'T tree = Leaf of 'T | Node of 'T*('T tree list);; let tr = Node(1,[ Node(2,[ Leaf(5)]); Node(3,[ Leaf(6); Leaf(7)]); Leaf(4)]);;

  5. Обход дерева • Обход – это процедура, которая посещает каждый узел дерева один и только один раз let rec iter f = function Leaf(T) -> f(T) | Node(T,L) -> (f(T); for t in L do iter f t done);; let iterh f = let rec itr n = function Leaf(T) -> f n T | Node(T,L) -> (f n T; for t in L do itr (n+1) t done) in itr 0;; let print_tree T = iterh (fun h x -> printf "%s%A\n" (spaces (h*3)) x) T;;

  6. Пример обработки: map map: (A → B) → A tree → B tree let rec map f = function Leaf(T) -> Leaf(f T) | Node(T,L) -> Node(f T,List.map (fun t -> map f t) L);; • print_tree (map (fun x->2*x) tr);; • В качестве упражнения опишите другие преобразования деревьев – отрубание листьев, maph, зеркальное переворачивание и т.д.

  7. Пример дерева общего вида: структура директорий • Дерево неявно порождается с помощью генератора на каждом уровне • Возможный способ задания дерева! • В качестве упражнения – построение структуры директорий в виде дерева в памяти в явном виде #light open System.IO let rec tree path ind = Directory.GetDirectories path |> Array.iter(fun dir -> printfn "%s%s" (spaces (ind*3)) dir; tree dir (ind+1) );;

  8. Чуть более сложный пример let rec du path = Directory.GetDirectories path |> Array.iter(fun dir -> let sz = Directory.GetFiles dir |> Array.map(fun f -> new FileInfo(f)) |> Array.fold_left (fun ac x -> ac+x.Length) 0L; printfn "%10d %s" sz dir; du dir );;

  9. + 6 * 3 3 7 1 2 1 4 Двоичные деревья • Двоичное дерево типа T – это • Пустое дерево Nil • Элемент типа T с двумя поддеревьями – левым и правым

  10. Взаимосвязь с дер.общ.вида • Двоичные деревья – это не есть частный случай деревьев общего вида: • Различие между левым и правым поддеревьями • Двоичное дерево может быть пустым 1 1 1 2 2 2

  11. Сведение дерева общего вида к двоичному • Любое дерево общего вида может быть преобразовано к двоичному 1 1 2 2 3 4 5 3 5 6 7 6 4 7

  12. Применение двоичных деревьев • Деревья поиска • Способ представления упорядоченных данных в памяти с эффективными алгоритмами добавления/удаления элемента и поиском • В неявном виде используются при определении структур данных типа ассоциативных таблиц, при индексировании и т.д. • Деревья выражений • Представление арифметических выражений с бинарными операторами

  13. 6 3 7 1 4 Описание двоичного дерева • Лист – это терминальный элемент без поддеревьев • Узел – это элемент, содержащий значение и поддеревья type 't btree = Node of 't * 't btree * 't btree | Nil;; let tr = Node(6, Node(3, Node(1,Nil,Nil), Node(4,Nil,Nil)), Node(7,Nil,Nil));;

  14. + * 3 1 2 Обходы двоичного дерева • КЛП, прямой, префиксный [+ * 1 2 3] • ЛКП, обратный, инфиксный [1*2+3] • ЛПК, концевой, постфиксный [1 2 * 3 +] • + 3 симметричных

  15. Процедура обхода let prefix root left right = (root(); left(); right());; let infix root left right = (left(); root(); right());; let postfix root left right = (left(); right(); root());; let iterh trav f t = let rec tr t h = match t with Node (x,L,R) -> trav (fun () -> (f x h)) (fun () -> tr L (h+1)) (fun () -> tr R (h+1)); | Nil -> () in tr t 0;; let print_tree T = iterh infix (fun x h -> printf "%s%A\n" (spaces h) x) T;;

  16. Отложенные вычисления • prefix/infix/postfix: • Переключатели типа обхода • (unit→unit)→ (unit→unit)→ (unit→unit)→unit • unit→unit – это функциональный тип • fun () -> … - создает функцию такого типа • () – вызов этой функции

  17. Обход с аккумулятором • Производит инфиксный обход дерева • Вычисляет f(a1,f(a2,…,f(an,init))..) • Дерево в список: let fold_infix init f t = let rec tr t x = match t with Node (z,L,R) -> tr R (f z (tr L x)) | Nil -> x in tr t init;; let tree_to_list T = fold_infix [] (fun x l -> x::l) T;;

More Related