SlideShare a Scribd company logo
Линейные структуры данных Федор Царев Спецкурс «Олимпиадное программирование» Лекция 1 01.12.2008, 08.12.2008 Санкт-Петербург, Гимназия 261
Цель лекции Изучить теоретические основы линейных структур данных Изучить методы их реализации на языке программирования  Pascal (Delphi)
Структуры данных Алгоритмы + структуры данных = программы (Никлаус Вирт) Способ организации хранения данных Набор операций и их свойства
Линейные структуры данных Наиболее просты для понимания Не содержат разветвлений Являются базовыми и используются во многих алгоритмах и более сложных структурах данных Список, стек, очередь, дек, …
Тип «запись» Служит для описания сущности, которая характеризуется несколькими параметрами type student = record name : string; class : integer; marks : array[1..10] of integer; end;
Поля записи Запись – набор полей var s : student; s.name := ‘Vasya’; writeln(s.name);
Указатели в языке  Pascal Указатель = адрес в памяти компьютера Выделение ( new )   и освобождение ( delete )   памяти Тип данных «указатель на» pstudent = ^student
Односвязный список Состоит из элементов (узлов) Данные и указатель на следующий узел type pnode = ^node; node = record data : integer; next : pnode; end; Указатель на начало списка  first
Операции со списком Добавление элемента ( add ) Поиск элемента ( find ) Удаление элемента ( remove )
Добавление элемента До добавления После добавления
Добавление элемента – программа procedure add(x : longint); var p : pnode; begin new(p); p^.data := x; p^.next := first; first := p; end;
Поиск элемента function find(x : integer) : boolean; var wp : pnode; begin wp := first; while (wp <> nil) do begin if (wp^.data = x) then begin result := true; exit; end; wp := wp^.next; end; result := false; end;
Удаление элемента Элемент необходимо найти и удалить До удаления После удаления
Удаление элемента Два случая удаление первого элемента удаление не первого элемента Необходимо знать не только удаляемый элемент, но и предыдущий
Программа (начало) procedure remove(x : integer); var cur, prev, tmp : pnode; begin if (first = nil) then begin exit; end; if (first^.data = x) then begin tmp := first; first := first^.next; delete(tmp); exit; end;
Программа (продолжение) prev := first; cur := first^.next; while (cur <> nil) do begin if (cur^.data = x) then begin prev^.next := cur^.next; delete(cur); exit; end; cur := cur^.next; prev := prev^.next; end; end;
Время работы операций   с односвязным списком add – O(1) –  константное время find – O(n) –  линейно зависит от числа элементов в списке remove – O(n)
Двусвязный список В каждом элементе хранится указатель не только на следующий, но и на предыдущий type pnode = ^node; node = record data : integer; next,  prev  : pnode; end;
Операции с двусвязным списком Добавление элемента ( add ) Поиск элемента ( find ) Удаление элемента ( remove )
Добавление элемента – программа procedure add(x : longint); var p : pnode; begin new(p); p^.data := x; p^.next := first; if (first <> nil) then begin first^.prev := p; end; first := p; end;
Поиск элемента Так же, как для односвязного function find(x : integer) : boolean; var wp : pnode; begin wp := first; while (wp <> nil) do begin if (wp^.data = x) then begin result := true; exit; end; wp := wp^.next; end; end;
Удаление элемента До удаления После удаления
Четыре случая Нет ни предыдущего, ни следующего Есть только предыдущий Есть только следующий Есть и предыдущий, и следующий
Удаление элемента  –  программа (начало) procedure remove(x : integer); var cur, prev, next : pnode; begin if (first = nil) then begin exit; end; end;
Удаление элемента  –  программа (продолжение) cur := first; while (cur <> nil) do begin if (cur^.data = x) then begin prev := cur^.prev; next := cur^.next; //  Обработка 4 случаев: //  следующие два слайда exit; end; cur := cur^.next; end;
Удаление элемента  –  обработка случаев (1, 2) if (prev=nil) and (next=nil) then   begin //  Элемент в списке один first := nil; delete(cur); end; if (prev <> nil) and (next = nil) then begin //  Удаляется последний в списке элемент prev^.next := nil; delete(cur); end;
Удаление элемента  –  обработка случаев (3, 4) if (prev = nil) and (next<>nil) then begin //  Удаляется первый в списке элемент first := next; delete(cur); end; if (prev<>nil) and (next<>nil) then begin //  Общий случай prev^.next := next; next^.prev := prev; delete(cur); end;
Запутались в случаях? Используйте  сторожевые элементы   ( sentinel elements )  –  специальные элементы, которые всегда присутствуют в списке, но не хранят никакой информации Необходимо два таких элемента – в начале и в конце списка
Список со сторожевыми элементами type pnode = ^node; node = record data : integer; next, prev : pnode; isSentinel : boolean; end;
Пустой список со сторожевыми элементами
Добавление в список procedure add(x : longint); var p : pnode; begin new(p); p^.data := x; p^.next := first; first^.prev := p; first := p; end;
Поиск function find(x : integer) : boolean; var wp : pnode; begin wp := first; while (wp <> nil) do begin if ( ( not  ( wp^.isSentinel ) ) and  (wp^.data = x) ) then begin result := true; exit; end; wp := wp^.next; end; result := false; end;
Удаление элемента procedure remove(x : integer); var cur, prev, next : pnode; begin cur := first; while (cur <> nil) do begin if ( ( not  ( cur^.isSentinel ) ) and  (cur^.data = x) ) then begin cur^.prev^.next := cur^.next; cur^.next^.prev := cur^.prev; delete(cur); exit; end; cur := cur^.next; end; end; Вместо четырех случаев – один!
Время работы операций   с двусвязным списком add – O(1) –  константное время find – O(n) –  линейно зависит от числа элементов в списке remove – O(n)
Стек Stack Принцип  LIFO (Last In – First Out) Используется в алгоритме обхода графа в глубину и при реализации рекурсии
Операции со стеком push(x) –  положить элемент в стек pop() –  взять элемент с верхушки стека isEmpty() –  пуст ли стек
Хранение стека в виде массива Массив  stack  элементов, хранящихся в стеке Переменная  top,  хранящая номер верхнего элемента
Программная реализация procedure push(x : integer); begin inc(top); stack[top] := x; end; function isEmpty() : boolean; begin result :=  ( top = 0 ) ; end;
Программная реализация function pop() : integer; begin if (isEmpty()) then begin //  Ошибка – извлекаем из  //  пустого стека exit; end; result := stack[top]; dec(top); end;
Очередь Queue Принцип  FIFO (First In – First Out) Используется в алгоритме обхода графа в ширину
Операции с очередью add –  добавить элемент remove –  извлечь элемент isEmpty –  проверить пустоту
Хранение очереди в виде массива Массив  queue  элементов, которые хранятся в очереди head –  номер первого элемента массива, который принадлежит очереди tail –  номер элемента, следующего за последним в очереди Элементы добавляются в хвост, извлекаются из головы
Программная реализация procedure add(x : integer); begin queue[tail] := x; inc(tail); end; function isEmpty() : boolean; begin result :=  ( head = tail ) ; end;
Программная реализация function remove() : boolean; begin if (isEmpty()) then begin //  Ошибка – извлекаем из  //  пустой очереди exit; end; result := queue[head]; inc(head); end;
Дек Dequeue = double-ended queue –  очередь с двумя концами
Операции с деком addLeft –  добавить слева removeLeft –  извлечь слева addRight –  добавить справа removeRight –  извлечь справа isEmpty –  проверить пустоту
Представление дека в виде массива Массив, хранящий элементы дека left –  левая граница дека right –  правая граница дека Надо быть аккуратным с границами массива, когда дек пуст Можно объявить массив  dequeue: array[-10..10] of longint;
Программная реализация function isEmpty() : boolean; begin result := left > right; end; procedure addRight(x : integer); begin inc(right); dequeue[right] := x; end;
Программная реализация procedure addLeft(x : integer); begin dec(left); dequeue[left] := x; end;
Программная реализация function removeLeft() : boolean; begin if (isEmpty()) then begin //  Ошибка – извлекаем из  //  пустого дека exit; end; result := dequeue[left]; inc(left); end;
Программная реализация function removeRight() : boolean; begin if (isEmpty()) then begin //  Ошибка – извлекаем из  //  пустого дека exit; end; result := dequeue[right]; dec(right); end;
Упражнение Реализовать стек, дек и очередь  на базе списков , а не   на базе массивов
Собственный менеджер памяти Использовать указатели не всегда удобно Выделение и освобождение памяти – достаточно медленные операции (порядка 100 тысяч операций в секунду, других операций можно совершить до 50 миллионов) Можно написать свой менеджер памяти!
Менеджер памяти Вместо памяти – массив memory : array[1..MAXMEM] of node; MAXMEM  –  «размер памяти» free –  номер первой свободной ячейки Вместо указателей – номера ячеек массива  memory -1  ↔   nil
Односвязный список
Добавление в список procedure add(x : longint); var p : integer; begin p := free; inc(free); memory[p].data := x; memory[p].next := first; first := p; end;
Поиск элемента function find(x : integer) : boolean; var wp : integer ; begin wp := first; while ( wp <> -1 ) do begin if (memory[wp].data = x) then begin result := true; exit; end; wp := memory[wp].next; end; result := false; end;
Удаление элемента (начало) procedure remove(x : integer); var cur, prev, tmp : integer; begin if ( first = -1 ) then begin exit; end; if (memory[first].data = x) then begin tmp := first; first := memory[first].next; exit; end;
Удаление элемента (продолжение) prev := first; cur := memory[first].next; while (cur <> -1) do begin if (memory[cur].data = x) then begin memory[prev].next := memory[cur].next; exit; end; cur := memory[cur].next; prev := memory[prev].next; end; end;
Упражнение Реализовать  двусвязный список  на собственном менеджере памяти
Выводы Односвязный и двусвязный списки основаны на указателях Для их реализации можно использовать как встроенный менеджер памяти ( new, delete ), так и собственный Стек, очередь и дек можно реализовать на основе списков и массивов Я рекомендую использовать свой менеджер памяти и реализацию стека, очереди и дека на базе массива
Спасибо за внимание! Вопросы?   Комментарии? [email_address]

More Related Content

PPT
02 сортировка и поиск
Fedor Tsarev
 
PDF
Лекция 4: Стеки и очереди
Mikhail Kurnosov
 
PDF
Олег Алистратов — Сортировка списков в Perl и Python
Yandex
 
PPTX
Reactive extensions
Sergey Teplyakov
 
PDF
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
Alexey Paznikov
 
PPT
List - списки
Unguryan Vitaliy
 
PPT
Запись вспомогательный алгоритмов на языка Паскаль
Andrey Dolinin
 
PPT
Программирование разветвляющихся алгоритмов
Andrey Dolinin
 
02 сортировка и поиск
Fedor Tsarev
 
Лекция 4: Стеки и очереди
Mikhail Kurnosov
 
Олег Алистратов — Сортировка списков в Perl и Python
Yandex
 
Reactive extensions
Sergey Teplyakov
 
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
Alexey Paznikov
 
List - списки
Unguryan Vitaliy
 
Запись вспомогательный алгоритмов на языка Паскаль
Andrey Dolinin
 
Программирование разветвляющихся алгоритмов
Andrey Dolinin
 

What's hot (20)

PPTX
Java 8. Lambdas
Nakraynikov Oleg
 
PPTX
Java8. Innovations
Nakraynikov Oleg
 
PDF
Алгоритмы и структуры данных осень 2013 лекция 2
Technopark
 
PDF
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
Alexey Paznikov
 
PDF
Алгоритмы и структуры данных весна 2014 лекция 2
Technopark
 
PDF
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
Alexey Paznikov
 
PPT
Mike ponomarenko java17-fork-v1.2
Alex Tumanoff
 
PDF
Python и его тормоза
Alexander Shigin
 
PDF
Лекция №5. Линейные структуры данных. Предмет "Структуры и алгоритмы обработк...
Nikolay Grebenshikov
 
PDF
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
Alexey Paznikov
 
PDF
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
Alexey Paznikov
 
PDF
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
Alexey Paznikov
 
PPT
Алгоритмическая конструкция Повторение
Andrey Dolinin
 
PDF
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
Alexey Paznikov
 
PPT
Презентация на тему: ЕГЭ информатика
2berkas
 
PPTX
Урок 8. Введение в редукцию графов
Система дистанционного обучения MyDLS
 
PPTX
Алгоритмы и структуры данных весна 2014 лекция 1
Technopark
 
PDF
Python: Модули и пакеты
Theoretical mechanics department
 
PDF
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
Alexey Paznikov
 
PPTX
C++ осень 2012 лекция 11
Technopark
 
Java 8. Lambdas
Nakraynikov Oleg
 
Java8. Innovations
Nakraynikov Oleg
 
Алгоритмы и структуры данных осень 2013 лекция 2
Technopark
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
Alexey Paznikov
 
Алгоритмы и структуры данных весна 2014 лекция 2
Technopark
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
Alexey Paznikov
 
Mike ponomarenko java17-fork-v1.2
Alex Tumanoff
 
Python и его тормоза
Alexander Shigin
 
Лекция №5. Линейные структуры данных. Предмет "Структуры и алгоритмы обработк...
Nikolay Grebenshikov
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
Alexey Paznikov
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
Alexey Paznikov
 
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
Alexey Paznikov
 
Алгоритмическая конструкция Повторение
Andrey Dolinin
 
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
Alexey Paznikov
 
Презентация на тему: ЕГЭ информатика
2berkas
 
Урок 8. Введение в редукцию графов
Система дистанционного обучения MyDLS
 
Алгоритмы и структуры данных весна 2014 лекция 1
Technopark
 
Python: Модули и пакеты
Theoretical mechanics department
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
Alexey Paznikov
 
C++ осень 2012 лекция 11
Technopark
 
Ad

Viewers also liked (20)

ODP
Gender roles and violence
Delia Rodriguez
 
PPT
No smoking
csvp
 
PPTX
Energia solar.
Natalia Hernández
 
PPT
Mobile Monday Brussels : SoLoMo - Corelio
Mobile Monday Brussels
 
PPTX
5 BS Facts About Data Privacy Everyone Thinks Are True
Social Media Today
 
PPT
Plantilla powerpoint
Victor Salinas
 
PDF
M2_Lesson_Plan_Magdalene
Magdalene Tan
 
PDF
MDN is easy!
Chris Mills
 
PDF
Avun ja tuen tarpeen arviointi kouluterveydenhuollossa
THL
 
PPT
Lakewood WA crime stats April 2010
Walter Neary
 
PDF
We're Doing It Wrong: Prototyping The Future Of The Web
Steve Hickey
 
PDF
Android SDK: How to Install
Jussi Pohjolainen
 
PDF
Catalogo compromiso-vs
Barbarita Rivera
 
PPTX
Content to conversion - Is Your Content Setting the Stage
CNW Group
 
PDF
2014 1 horarios 10 a (1)
Ramón Díaz
 
PPTX
Reforma Hacendaria
UNID
 
PDF
Besluit houders van dieren en diergeneeskundigen
Harm Kiezebrink
 
PPT
Business Expansion Planning Srategy
Indore Colour Organics Ltd.
 
PPT
No Smoking
csvp
 
PPTX
GOBIERNO ELECTRÓNICO COMO HERRAMIENTA DE GESTIÓN PÚBLICA EN VENEZUELA
Maribel Ch
 
Gender roles and violence
Delia Rodriguez
 
No smoking
csvp
 
Energia solar.
Natalia Hernández
 
Mobile Monday Brussels : SoLoMo - Corelio
Mobile Monday Brussels
 
5 BS Facts About Data Privacy Everyone Thinks Are True
Social Media Today
 
Plantilla powerpoint
Victor Salinas
 
M2_Lesson_Plan_Magdalene
Magdalene Tan
 
MDN is easy!
Chris Mills
 
Avun ja tuen tarpeen arviointi kouluterveydenhuollossa
THL
 
Lakewood WA crime stats April 2010
Walter Neary
 
We're Doing It Wrong: Prototyping The Future Of The Web
Steve Hickey
 
Android SDK: How to Install
Jussi Pohjolainen
 
Catalogo compromiso-vs
Barbarita Rivera
 
Content to conversion - Is Your Content Setting the Stage
CNW Group
 
2014 1 horarios 10 a (1)
Ramón Díaz
 
Reforma Hacendaria
UNID
 
Besluit houders van dieren en diergeneeskundigen
Harm Kiezebrink
 
Business Expansion Planning Srategy
Indore Colour Organics Ltd.
 
No Smoking
csvp
 
GOBIERNO ELECTRÓNICO COMO HERRAMIENTA DE GESTIÓN PÚBLICA EN VENEZUELA
Maribel Ch
 
Ad

Similar to 01 линейные структуры данных (20)

PDF
ОПК № 5 – Составные типы данных, списки
Vladimir Parfinenko
 
PDF
C++ Базовый. Занятие 07.
Igor Shkulipa
 
PDF
Абстрактные типы данных, контейнеры и списки
Olga Maksimenkova
 
PPT
Лекция 3 Элементарные структуры данных Часть 1
simple_people
 
PPT
03 двоичные деревья поиска и очередь с приоритетами
Fedor Tsarev
 
PDF
Абстрактные типы данных, последовательности, списки
Olga Maksimenkova
 
PPT
списки (2008)
vivalis2010
 
PDF
Абстрактные типы данных. Списки
Olga Maksimenkova
 
PPT
лабораторная работа №7
Анюта Кислова
 
PPT
лабораторная работа №7
Gulnaz Shakirova
 
PPT
лекция 4
student_kai
 
PDF
Лекция о языке программирования Haskell
husniyarova
 
PDF
Лекция 3: Бинарный поиск. Связные списки
Mikhail Kurnosov
 
PPTX
ПРОЦЕДУРЫ
Colegiul de Industrie Usoara
 
PPTX
Algo 00
Alex Tarasov
 
PPT
лекция 4
Zhanna Kazakova
 
PPTX
вспомогательные алгоритмы
Елена Ключева
 
ОПК № 5 – Составные типы данных, списки
Vladimir Parfinenko
 
C++ Базовый. Занятие 07.
Igor Shkulipa
 
Абстрактные типы данных, контейнеры и списки
Olga Maksimenkova
 
Лекция 3 Элементарные структуры данных Часть 1
simple_people
 
03 двоичные деревья поиска и очередь с приоритетами
Fedor Tsarev
 
Абстрактные типы данных, последовательности, списки
Olga Maksimenkova
 
списки (2008)
vivalis2010
 
Абстрактные типы данных. Списки
Olga Maksimenkova
 
лабораторная работа №7
Анюта Кислова
 
лабораторная работа №7
Gulnaz Shakirova
 
лекция 4
student_kai
 
Лекция о языке программирования Haskell
husniyarova
 
Лекция 3: Бинарный поиск. Связные списки
Mikhail Kurnosov
 
ПРОЦЕДУРЫ
Colegiul de Industrie Usoara
 
Algo 00
Alex Tarasov
 
лекция 4
Zhanna Kazakova
 
вспомогательные алгоритмы
Елена Ключева
 

More from Fedor Tsarev (11)

PPTX
We are the champions: programming world champions from Russia. Why and what for?
Fedor Tsarev
 
PPTX
Becoming a World Champion in Programming: Keep Calm and Compete
Fedor Tsarev
 
PPTX
Сборка генома: мифы и реальность. Доклад на пленарном заседании III Всероссий...
Fedor Tsarev
 
PDF
On NP-Hardness of the Paired de Bruijn Sound Cycle Problem
Fedor Tsarev
 
PPTX
Сборка генома de novo: мифы и реальность
Fedor Tsarev
 
PDF
Talk at dnGASP workshop, April 5, 2011
Fedor Tsarev
 
PPTX
Доклад на семинаре в лаборатории алгоритмической биологии АУ
Fedor Tsarev
 
PPT
Problem solving on acm international collegiate programming contest
Fedor Tsarev
 
PPT
05 динамическое программирование
Fedor Tsarev
 
PPT
05 динамическое программирование
Fedor Tsarev
 
PPT
04 динамическое программирование - основные концепции
Fedor Tsarev
 
We are the champions: programming world champions from Russia. Why and what for?
Fedor Tsarev
 
Becoming a World Champion in Programming: Keep Calm and Compete
Fedor Tsarev
 
Сборка генома: мифы и реальность. Доклад на пленарном заседании III Всероссий...
Fedor Tsarev
 
On NP-Hardness of the Paired de Bruijn Sound Cycle Problem
Fedor Tsarev
 
Сборка генома de novo: мифы и реальность
Fedor Tsarev
 
Talk at dnGASP workshop, April 5, 2011
Fedor Tsarev
 
Доклад на семинаре в лаборатории алгоритмической биологии АУ
Fedor Tsarev
 
Problem solving on acm international collegiate programming contest
Fedor Tsarev
 
05 динамическое программирование
Fedor Tsarev
 
05 динамическое программирование
Fedor Tsarev
 
04 динамическое программирование - основные концепции
Fedor Tsarev
 

01 линейные структуры данных

  • 1. Линейные структуры данных Федор Царев Спецкурс «Олимпиадное программирование» Лекция 1 01.12.2008, 08.12.2008 Санкт-Петербург, Гимназия 261
  • 2. Цель лекции Изучить теоретические основы линейных структур данных Изучить методы их реализации на языке программирования Pascal (Delphi)
  • 3. Структуры данных Алгоритмы + структуры данных = программы (Никлаус Вирт) Способ организации хранения данных Набор операций и их свойства
  • 4. Линейные структуры данных Наиболее просты для понимания Не содержат разветвлений Являются базовыми и используются во многих алгоритмах и более сложных структурах данных Список, стек, очередь, дек, …
  • 5. Тип «запись» Служит для описания сущности, которая характеризуется несколькими параметрами type student = record name : string; class : integer; marks : array[1..10] of integer; end;
  • 6. Поля записи Запись – набор полей var s : student; s.name := ‘Vasya’; writeln(s.name);
  • 7. Указатели в языке Pascal Указатель = адрес в памяти компьютера Выделение ( new ) и освобождение ( delete ) памяти Тип данных «указатель на» pstudent = ^student
  • 8. Односвязный список Состоит из элементов (узлов) Данные и указатель на следующий узел type pnode = ^node; node = record data : integer; next : pnode; end; Указатель на начало списка first
  • 9. Операции со списком Добавление элемента ( add ) Поиск элемента ( find ) Удаление элемента ( remove )
  • 10. Добавление элемента До добавления После добавления
  • 11. Добавление элемента – программа procedure add(x : longint); var p : pnode; begin new(p); p^.data := x; p^.next := first; first := p; end;
  • 12. Поиск элемента function find(x : integer) : boolean; var wp : pnode; begin wp := first; while (wp <> nil) do begin if (wp^.data = x) then begin result := true; exit; end; wp := wp^.next; end; result := false; end;
  • 13. Удаление элемента Элемент необходимо найти и удалить До удаления После удаления
  • 14. Удаление элемента Два случая удаление первого элемента удаление не первого элемента Необходимо знать не только удаляемый элемент, но и предыдущий
  • 15. Программа (начало) procedure remove(x : integer); var cur, prev, tmp : pnode; begin if (first = nil) then begin exit; end; if (first^.data = x) then begin tmp := first; first := first^.next; delete(tmp); exit; end;
  • 16. Программа (продолжение) prev := first; cur := first^.next; while (cur <> nil) do begin if (cur^.data = x) then begin prev^.next := cur^.next; delete(cur); exit; end; cur := cur^.next; prev := prev^.next; end; end;
  • 17. Время работы операций с односвязным списком add – O(1) – константное время find – O(n) – линейно зависит от числа элементов в списке remove – O(n)
  • 18. Двусвязный список В каждом элементе хранится указатель не только на следующий, но и на предыдущий type pnode = ^node; node = record data : integer; next, prev : pnode; end;
  • 19. Операции с двусвязным списком Добавление элемента ( add ) Поиск элемента ( find ) Удаление элемента ( remove )
  • 20. Добавление элемента – программа procedure add(x : longint); var p : pnode; begin new(p); p^.data := x; p^.next := first; if (first <> nil) then begin first^.prev := p; end; first := p; end;
  • 21. Поиск элемента Так же, как для односвязного function find(x : integer) : boolean; var wp : pnode; begin wp := first; while (wp <> nil) do begin if (wp^.data = x) then begin result := true; exit; end; wp := wp^.next; end; end;
  • 22. Удаление элемента До удаления После удаления
  • 23. Четыре случая Нет ни предыдущего, ни следующего Есть только предыдущий Есть только следующий Есть и предыдущий, и следующий
  • 24. Удаление элемента – программа (начало) procedure remove(x : integer); var cur, prev, next : pnode; begin if (first = nil) then begin exit; end; end;
  • 25. Удаление элемента – программа (продолжение) cur := first; while (cur <> nil) do begin if (cur^.data = x) then begin prev := cur^.prev; next := cur^.next; // Обработка 4 случаев: // следующие два слайда exit; end; cur := cur^.next; end;
  • 26. Удаление элемента – обработка случаев (1, 2) if (prev=nil) and (next=nil) then begin // Элемент в списке один first := nil; delete(cur); end; if (prev <> nil) and (next = nil) then begin // Удаляется последний в списке элемент prev^.next := nil; delete(cur); end;
  • 27. Удаление элемента – обработка случаев (3, 4) if (prev = nil) and (next<>nil) then begin // Удаляется первый в списке элемент first := next; delete(cur); end; if (prev<>nil) and (next<>nil) then begin // Общий случай prev^.next := next; next^.prev := prev; delete(cur); end;
  • 28. Запутались в случаях? Используйте сторожевые элементы ( sentinel elements ) – специальные элементы, которые всегда присутствуют в списке, но не хранят никакой информации Необходимо два таких элемента – в начале и в конце списка
  • 29. Список со сторожевыми элементами type pnode = ^node; node = record data : integer; next, prev : pnode; isSentinel : boolean; end;
  • 30. Пустой список со сторожевыми элементами
  • 31. Добавление в список procedure add(x : longint); var p : pnode; begin new(p); p^.data := x; p^.next := first; first^.prev := p; first := p; end;
  • 32. Поиск function find(x : integer) : boolean; var wp : pnode; begin wp := first; while (wp <> nil) do begin if ( ( not ( wp^.isSentinel ) ) and (wp^.data = x) ) then begin result := true; exit; end; wp := wp^.next; end; result := false; end;
  • 33. Удаление элемента procedure remove(x : integer); var cur, prev, next : pnode; begin cur := first; while (cur <> nil) do begin if ( ( not ( cur^.isSentinel ) ) and (cur^.data = x) ) then begin cur^.prev^.next := cur^.next; cur^.next^.prev := cur^.prev; delete(cur); exit; end; cur := cur^.next; end; end; Вместо четырех случаев – один!
  • 34. Время работы операций с двусвязным списком add – O(1) – константное время find – O(n) – линейно зависит от числа элементов в списке remove – O(n)
  • 35. Стек Stack Принцип LIFO (Last In – First Out) Используется в алгоритме обхода графа в глубину и при реализации рекурсии
  • 36. Операции со стеком push(x) – положить элемент в стек pop() – взять элемент с верхушки стека isEmpty() – пуст ли стек
  • 37. Хранение стека в виде массива Массив stack элементов, хранящихся в стеке Переменная top, хранящая номер верхнего элемента
  • 38. Программная реализация procedure push(x : integer); begin inc(top); stack[top] := x; end; function isEmpty() : boolean; begin result := ( top = 0 ) ; end;
  • 39. Программная реализация function pop() : integer; begin if (isEmpty()) then begin // Ошибка – извлекаем из // пустого стека exit; end; result := stack[top]; dec(top); end;
  • 40. Очередь Queue Принцип FIFO (First In – First Out) Используется в алгоритме обхода графа в ширину
  • 41. Операции с очередью add – добавить элемент remove – извлечь элемент isEmpty – проверить пустоту
  • 42. Хранение очереди в виде массива Массив queue элементов, которые хранятся в очереди head – номер первого элемента массива, который принадлежит очереди tail – номер элемента, следующего за последним в очереди Элементы добавляются в хвост, извлекаются из головы
  • 43. Программная реализация procedure add(x : integer); begin queue[tail] := x; inc(tail); end; function isEmpty() : boolean; begin result := ( head = tail ) ; end;
  • 44. Программная реализация function remove() : boolean; begin if (isEmpty()) then begin // Ошибка – извлекаем из // пустой очереди exit; end; result := queue[head]; inc(head); end;
  • 45. Дек Dequeue = double-ended queue – очередь с двумя концами
  • 46. Операции с деком addLeft – добавить слева removeLeft – извлечь слева addRight – добавить справа removeRight – извлечь справа isEmpty – проверить пустоту
  • 47. Представление дека в виде массива Массив, хранящий элементы дека left – левая граница дека right – правая граница дека Надо быть аккуратным с границами массива, когда дек пуст Можно объявить массив dequeue: array[-10..10] of longint;
  • 48. Программная реализация function isEmpty() : boolean; begin result := left > right; end; procedure addRight(x : integer); begin inc(right); dequeue[right] := x; end;
  • 49. Программная реализация procedure addLeft(x : integer); begin dec(left); dequeue[left] := x; end;
  • 50. Программная реализация function removeLeft() : boolean; begin if (isEmpty()) then begin // Ошибка – извлекаем из // пустого дека exit; end; result := dequeue[left]; inc(left); end;
  • 51. Программная реализация function removeRight() : boolean; begin if (isEmpty()) then begin // Ошибка – извлекаем из // пустого дека exit; end; result := dequeue[right]; dec(right); end;
  • 52. Упражнение Реализовать стек, дек и очередь на базе списков , а не на базе массивов
  • 53. Собственный менеджер памяти Использовать указатели не всегда удобно Выделение и освобождение памяти – достаточно медленные операции (порядка 100 тысяч операций в секунду, других операций можно совершить до 50 миллионов) Можно написать свой менеджер памяти!
  • 54. Менеджер памяти Вместо памяти – массив memory : array[1..MAXMEM] of node; MAXMEM – «размер памяти» free – номер первой свободной ячейки Вместо указателей – номера ячеек массива memory -1 ↔ nil
  • 56. Добавление в список procedure add(x : longint); var p : integer; begin p := free; inc(free); memory[p].data := x; memory[p].next := first; first := p; end;
  • 57. Поиск элемента function find(x : integer) : boolean; var wp : integer ; begin wp := first; while ( wp <> -1 ) do begin if (memory[wp].data = x) then begin result := true; exit; end; wp := memory[wp].next; end; result := false; end;
  • 58. Удаление элемента (начало) procedure remove(x : integer); var cur, prev, tmp : integer; begin if ( first = -1 ) then begin exit; end; if (memory[first].data = x) then begin tmp := first; first := memory[first].next; exit; end;
  • 59. Удаление элемента (продолжение) prev := first; cur := memory[first].next; while (cur <> -1) do begin if (memory[cur].data = x) then begin memory[prev].next := memory[cur].next; exit; end; cur := memory[cur].next; prev := memory[prev].next; end; end;
  • 60. Упражнение Реализовать двусвязный список на собственном менеджере памяти
  • 61. Выводы Односвязный и двусвязный списки основаны на указателях Для их реализации можно использовать как встроенный менеджер памяти ( new, delete ), так и собственный Стек, очередь и дек можно реализовать на основе списков и массивов Я рекомендую использовать свой менеджер памяти и реализацию стека, очереди и дека на базе массива
  • 62. Спасибо за внимание! Вопросы? Комментарии? [email_address]