- •Структуры данных и алгоритмы их обработки (Учебное пособие)
- •Москва 2007
- •1. Структуры данных и алгоритмы 6
- •1.2. Информация и ее представление
- •1.2.1. Природа информации
- •1.2.2. Хранение информации
- •1.2.3. Классификация структур данных
- •1.3. Операции над структурами данных
- •1.4. Порядок алгоритма
- •1.5. Структурность данных и технологии программирования
- •Контрольные вопросы
- •2. Простые структуры данных
- •2.1. Порядковые типы
- •2.2. Целочисленный тип
- •2.3. Символьный тип
- •2.4. Перечисляемый тип
- •2.5. Интервальный тип
- •2.6. Логический тип
- •2.7. Битовый тип
- •2.8. Вещественный тип
- •2.9. Указательный тип
- •Контрольные вопросы
- •3. Объектные типы данных
- •3.1. Объявление и реализация классов
- •Interface
- •Implementation
- •3.2. Директивы видимости
- •3.3. Свойства классов
- •3.4. Структурированная обработка ошибок
- •3.5. Применение объектов
- •Контрольные вопросы
- •4. Статические структуры данных
- •4.1. Векторы
- •4.2. Массивы
- •4.3. Множества
- •4.4. Записи
- •4.5. Таблицы
- •4.6. Операции над статическими структурами
- •4.6.1. Алгоритмы поиска
- •4.6.2. Алгоритмы сортировки
- •Самые медленные алгоритмы сортировки
- •Быстрые алгоритмы сортировки
- •Самые быстрые алгоритмы сортировки
- •Сортировка слиянием
- •Контрольные вопросы
- •5. Полустатические структуры данных
- •5.1. Стеки
- •5.1.1. Стеки в вычислительных системах
- •5.2. Очереди fifo
- •5.2.1. Очереди с приоритетами
- •5.2.2. Очереди в вычислительных системах
- •5.3. Деки
- •5.3.1. Деки в вычислительных системах
- •5.4. Строки
- •5.4.1. Операции над строками
- •5.4.2. Представление строк в памяти
- •3 A b d 8 p q r s t u V w
- •V w ptr nil
- •1 8 П р е д с т а в
- •2 7 ? Л е н и е ?
- •1 8 С т р о к и з
- •1 8 В е н ь я м и
- •1 8 С у п р а в л
- •1 8 Я е м о й д л
- •1 4 И н о й ? ? ? ? nil
- •6.2. Связные линейные списки
- •6.2.1. Машинное представление связных линейных списков
- •Inf next
- •Inf next
- •Inf nil
- •6.2.2. Реализация операций над связными линейными списками
- •Inf next
- •Inf next
- •Inf next
- •Inf next
- •Inf next
- •Inf next
- •Inf next
- •Inf next
- •Inf next
- •Inf next
- •Inf next
- •Inf next
- •6.2.3. Применение линейных списков
- •6.3. Нелинейные разветвленные списки
- •6.3.1. Основные понятия
- •6.3.2. Представление списковых структур в памяти
- •6.3.3. Операции обработки списков
- •6.4. Язык программирования lisp
- •6.5. Управление динамически выделяемой памятью
- •Контрольные вопросы
- •7. Нелинейные структуры данных
- •7.1. Графы и деревья
- •(B) (a) (b) (a)
- •V0 v1 v2 v5 v6 v3 v4 v7 v8 v9 v10 (v0) (v1) (v7) (v8) (v9) (v10) (v3) (v2) (v4) (v5) (v6)
- •7.3. Бинарные деревья
- •7.3.1. Представление бинарных деревьев
- •7.3.2. Прохождение бинарных деревьев
- •7.4. Алгоритмы на деревьях
- •7.4.1. Сортировка с прохождением бинарного дерева
- •7.4.2. Сортировка методом турнира с выбыванием
- •7.4.3. Применение бинарных деревьев для сжатия информации
- •7.4.4. Представление выражений с помощью деревьев
- •7.5. Представление сильноветвящихся деревьев
- •Контрольные вопросы
- •8. Методы ускорения доступа к данным
- •8.1. Хеширование данных
- •8.1.1. Функции хеширования
- •8.1.2. Оценка качества хеш-функции
- •8.1.3. Методы разрешения коллизий
- •8.1.4. Переполнение таблицы и рехеширование
- •8.2. Организация данных для поиска по вторичным ключам
- •8.2.1. Инвертированные индексы
- •8.2.2. Битовые карты
- •Контрольные вопросы
- •Листинги рабочих примеров
- •1. Создание и управление списковыми объектами
- •Interface
- •Implementation
- •Interface
- •Implementation
- •3. Моделирование работы стека
- •Interface
- •Implementation
- •Interface
- •Implementation
- •4. Создание и редактирование бинарных деревьев
- •5. Создание и редактирование сильноветвящихся деревьев
- •Задания для самостоятельной работы
- •Литература
- •144Кафедра Вычислительной Техники и Программирования Московского Государственного Открытого Университета
(2) … prevInf next
Inf next
Inf next
Inf next
…
cur
(1)
Рис. 6.4. Вставка элемента в середину 1-связного списка.
Следующий пример демонстрирует реализацию этой операции.
{ Вставка элемента в середину 1-связного списка }
procedure InsertSll(prev: sllptr; inf: data);
{ prev - адрес предыдущего эл-та; inf - данные нового элемента }
var cur: sllptr; { адрес нового элемента }
begin
{ Создание нового элемента – выделение
памяти для него и запись инф. части }
New(cur);
cur^.inf:=inf;
{ элемент, следовавший за предыдущим
теперь будет следовать за новым }
cur^.next:=prev^.next;
{ новый элемент следует за предыдущим }
prev^.next:=cur;
end;
Рисунок 6.5 представляет вставку в двухсвязный список.
(2) (1) (3) (4) cur prev … …
PREV
INF NEXT
PREV
INF NEXT
PREV
INF NEXT
PREV
INF NEXT … …
Рис. 6.5. Вставка элемента в середину 2-связного списка.
Приведенные примеры обеспечивают вставку в середину списка, но не могут быть применены для вставки в начало списка. В этом случае должен модифицироваться указатель на начало списка, как показано на рис. 6.6.
head
– указатель
на начало cur (1) (2) …Inf next
Inf next
Inf next
Рис. 6.6. Вставка элемента в начало 1-связного списка.
В примере процедура выполняет вставку элемента в любое место односвязного списка.
{ Вставка элемента в любое место 1-связного списка }
procedure InsertSll(
var
{ указатель на начало списка, может измениться в
процедуре, если head=nil - список пустой }
head: sllptr;
{ указатель на элемент, после которого делается вставка,
если prev=nil - вставка перед первым элементом }
prev: sllptr;
inf: data { данные нового элемента }
cur: sllptr); { адрес нового элемента }
begin
{ выделение памяти для нового элемента и запись его инф. части }
New(cur);
cur^.inf:=inf;
{ если есть предыдущий элемент - вставка в середину списка }
if prev <> nil then
begin
cur^.next:=prev^.next;
prev^.next:=cur;
end else
{ вставка в начало списка }
begin
{ новый элемент указывает на бывший первый элемент списка;
если head = nil, то новый элемент будет и последним элементом списка }
cur^.next:=head;
{ новый элемент становится первым в списке,
указатель на начало теперь указывает на него }
head:=cur;
end;
end;
Удаление элемента из списка. Удаление элемента из односвязного списка показано на рис. 6.7. Процедуру удаления легко выполнить, если известен адрес элемента, предшествующего удаляемому (prev на рис. 6.7. а). Однако на рис. 6.7 и в примере приводится процедура для случая, когда удаляемый элемент задается своим адресом del.
prev … INF
NEXT INF
NEXT delInf next
…
а).
del head INF
NEXT INF
NEXT …
б).
Рис. 6.7. Удаление элемента из 1-связного списка из середины списка (а) и из начала (б).
Процедура обеспечивает удаление из середины и из начала списка.
{ Удаление элемента из любого места 1-связного списка }
procedure DeleteSll(
var head: sllptr; { указатель на начало списка, может измениться в процедуре }
del: sllptr); { указатель на элемент, который удаляется }
var prev: sllptr; { адрес предыдущего элемента }
begin
{ попытка удаления из пустого списка расценивается как ошибка
(в последующих примерах этот случай учитываться не будет) }
if head = nil then
begin
Writeln('Ошибка!');
Halt;
end;
{ если удаляемый элемент - первый в списке,
то следующий за ним становится первым }
if del = head then
head:=del^.next else
{ удаление из середины списка }
begin
{ приходится искать элемент, предшествующий удаляемому; поиск производится перебором списка с самого его начала, пока не будет найдет элемент, поле next которого совпадает с адресом удаляемого элемента }
prev:=head^.next;
while (prev^.next <> del) and (prev^.next <> nil) do
prev:=prev^.next;
if prev^.next = nil then
begin
{ это случай, когда перебран весь список, но элемент не найден,
он отсутствует в списке; расценивается как ошибка }
Writeln('Ошибка!');
Halt;
end;
{ предыдущий элемент теперь указывает на следующий за удаляемым }
prev^.next:=del^.next;
end;
{ элемент исключен из списка, теперь можно освободить занимаемую им память }
Dispose(del);
end;
Удаление элемента из двухсвязного списка требует коррекции большего числа указателей, как показано на рис. 6.8. Процедура удаления, чем для односвязного списка, так как в ней не нужен поиск предыдущего элемента (выбирается по указателю назад).
(1) (2) del … …
PREV
INF NEXT
PREV
INF NEXT
PREV
INF NEXT … …
Рис. 6.8. Удаление элемента из 2-связного списка.
Перестановка элементов списка.Изменчивость динамических структур предполагает не только изменения размера структуры, но и изменения связей между элементами. В качестве примера приведем перестановку двух соседних элементов списка (рис. 6.9). В алгоритме предполагается известным адрес элемента, предшествующего паре, в которой производится перестановка. В алгоритме также не учитывается случай перестановки первого и второго элементов.