slide1
Download
Skip this Video
Download Presentation
Функциональное программирование

Loading in 2 Seconds...

play fullscreen
1 / 17

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


  • 154 Views
  • Uploaded on

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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Функциональное программирование' - kaiya


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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide1

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

Факультет инноваций и высоких технологий

Московский физико-технический институт

slide2

Лекция 12

Деревья

slide3
Определение

Дерево общего вида типа T – это

    • Элемент типа T с присоединенными к нему 0 и более деревьями типа T
  • Формально – связанный граф без циклов

1

2

3

4

5

6

7

slide4

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)]);;

slide5
Обход дерева
  • Обход – это процедура, которая посещает каждый узел дерева один и только один раз

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;;

slide6
Пример обработки: 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, зеркальное переворачивание и т.д.
slide7
Пример дерева общего вида: структура директорий
  • Дерево неявно порождается с помощью генератора на каждом уровне
  • Возможный способ задания дерева!
  • В качестве упражнения – построение структуры директорий в виде дерева в памяти в явном виде

#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)

);;

slide8
Чуть более сложный пример

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

);;

slide9

+

6

*

3

3

7

1

2

1

4

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

1

1

1

2

2

2

slide11
Сведение дерева общего вида к двоичному
  • Любое дерево общего вида может быть преобразовано к двоичному

1

1

2

2

3

4

5

3

5

6

7

6

4

7

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

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));;

slide14

+

*

3

1

2

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

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;;

slide16
Отложенные вычисления
  • prefix/infix/postfix:
    • Переключатели типа обхода
    • (unit→unit)→ (unit→unit)→ (unit→unit)→unit
  • unit→unit – это функциональный тип
  • fun () -> … - создает функцию такого типа
  • () – вызов этой функции
slide17
Обход с аккумулятором
  • Производит инфиксный обход дерева
  • Вычисляет 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;;

ad