
- •Теоретический раздел лекции Тема 1. Программирование с использованием рекурсии
- •1.1. Cтратегии решения задачи разбиением ее на подзадачи
- •1.2. Программирование рекуррентных соотношений
- •Var z:extended;
- •1.3. Условия окончания рекурсии
- •1.4. О целесообразности использования рекурсии
- •Var I,X,y,z:word;
- •1.5 Правила выбора программной реализации рекуррентных соотношений
- •Тема 2. Задачи перебора вариантов
- •2.1. Модель дерева решений
- •2.2. Задача оптимального выбора (задача о рюкзаке)
- •2.3. Метод полного перебора двоичного дерева
- •Var wt,ct:extended;
- •Var j,k:byte;
- •If k in s then begin
- •Var j:byte;
- •Var j:byte;
- •Var wt1,oct1:byte;
- •2.4. Метод ветвей и границ
- •Var n,I:byte;
- •Var wt1,oct1:Extended;
- •Include(s,I);
- •If I in Sopt then writeln(I,a[I].W,a[I].C);
- •2.5. Эвристические методы
- •Тема 3. Поиск и сортировка массивов записей
- •3.1. Применимость сортировки и поиска
- •3.2. Массив записей и поиск в нем
- •Var m:word;
- •3.3. Сортировки массивов
- •Var c: mas; I,j,k:word;
- •Var m:word;
- •Var I,j:Word;
- •Var I,j,l,r:Word; X:Tk; w:Tzp;
- •Тема 4. Связанные списки с использованием рекурсивных данных
- •4.1. Список, стек, очередь
- •4.2. Списки на основе динамических массивов
- •Inherited create;
- •Var turn:Tlist; с1,c2:Tinf;
- •4.3. Рекурсивные данные и однонаправленные списки
- •Inherited create;
- •Var stec,st1,turn,tr1:Tlist; inf:Tinf;
- •4.4. Начальное формирование, добавление и удаление элементов однонаправленного списка
- •4.5. Разновидности связанных списков
- •Inf:Tinf;
- •Тема 5. Поиск и сортировки на связанных линейных списках
- •5.1. Поиск в однонаправленных списках
- •5.2. Сортировка однонаправленных списков
- •1 3Var Inf:tInf;
- •Тема 6. Использование линейных связанных списков
- •6.1. Вычисления арифметических выражений
- •Var ch,ch1,ch2,chr:char;
- •I:byte;ch,ch1:char;
- •6.2. Сложение больших целых чисел
- •Var u,V,s,t:byte;
- •6.3. Работа с разреженными матрицами
- •Inf:Tinf;
- •Inf:tInf;
- •Var proot,p:Ptree;
- •Var bl:boolean;
- •7.2. Бинарное дерево поиска
- •7.3. Основные операции с бинарным деревом поиска
- •Inf:tInf;
- •Var d1:Tree; c:Tinf; k:Tkey;
- •Var bl:Boolean;
- •Var m:Word;
- •Var p:Ttree; m:Word;
- •Тема 8. Хеширование
- •8.1. Что такое хеширование
- •8.2. Схема хеширования
- •Interface
- •Inf:Tinf;
- •8.4. Другие способы хеширования
- •Практический раздел Указания по выбору варианта
- •Индивидуальные практические работы и контрольные работы
- •Индивидуальная практическая работа №1. Программирование с использованием рекурсии
- •1.1. Понятие рекурсии
- •1.2. Порядок выполнения работы
- •1.2.1. Пример решения задачи
- •Индивидуальная практическая работа №2. Организация однонаправленного списка на основе рекурсивных типов данных в виде стека
- •2.1. Основные понятия и определения
- •Inf:tInf; // информация
- •Контрольная работа №1. Программирование с использованием деревьев на основе рекурсивных типов данных
- •1.1. Понятие древовидной структуры
- •Inf:tInf;
- •1.2. Компонент tTreeView
- •1.3. Бинарное дерево поиска
- •Основные операции с двоичным деревом поиска
- •1.4. Порядок написания программы
- •Inf:tInf;
- •Inherited Free;
- •Var tr:Ttree;
- •1.5. Индивидуальные задания
- •Курсовая работа
- •Литература
Var c: mas; I,j,k:word;
begin
i:=L; k=1; j:=m+1;
while (i<=m) and (j<=R) do
if a[i].k<a[j].k then
begin c[k]:=a[i]; Inc(i); Inc(k) end;
else
begin c[k]:=a[j]; Inc(j); Inc(k) end;
while i<=m do
begin c[k]:=a[i]; Inc(i); inc(k) end;
while j<=R do
begin c[k]:=a[j]; Inc(j); Inc(k) end;
k=0;
for i:=L to R do
begin Inc(k); a[i]:=c[k] end;
end;
Рекурсивный алгоритм сортировки основан на следующей последовательности подзадач:
Тривиальная задача:
Массив из одного элемента отсортирован
Элементарная подзадача:
Слияние двух смежных отсортированных участков в один отсортированный.
Рекурсивное соотношение:
Массив a[1..n] разбивается на 2 смежных массива a[1..m], a[m+1..n]. Каждый из смежных участков сортируется, после чего они сливаются в один отсортированный:
Procedure SortSlip (n: word);
Procedure Slip(L,m,R:word);//сюда вставить!
Begin
End;
Procedure SrSl (L, R:word);
Var m:word;
begin
if L<>R then begin
m:=L+R div 2
SrSl(L,m);
SrSL(m+1,R);
Slip(L,m,R);
end;
end;
begin
SrSl(1,n)
end;
При реализации происходит разбиение массива на последовательность смежных участков пока в каждом участке не окажется по одному элементу, затем в обратном порядке происходит слияние смежных участков. Это один из самых эффективных по времени методов, однако затратный по памяти, поэтому он используется при реализации алгоритмов внешней сортировки.
Метод Д. Шелла, (1959) усовершенствование метода прямого включения.Его идея: сначала сортируются элементы, отстоящие на 4 позиции (четверная сортировка), затем отстоящие на две и наконец на одну. Такая стратегия позволяет существенно уменьшить количество сдвигов элементов.
Сортировка с помощью дерева метод HeapSort, (пирамидальная), Д. Уильямсон, (1964) усовершенствование метода прямого выбора. Идея его в том, что при поиске первого минимального элемента запоминается попарное упорядочение элементов и эта информация используется в последующем. Запоминание упорядоченности производится в специальной древовидной структуре, похожей на пирамиду.
Сортировка с помощью разделения, метод QuickSort, Ч. Хоар, (1962), улучшенная версия пузырьковой сортировки. На сегодняшний день это самый эффективный метод сортировки.
Идея метода разделения Хоара в следующем:
Выберем значение ключа среднего m-го элемента x=a[m].k (m можно выбирать либо делением пополам, либо случайным образом, как рекомендует автор). Будем просматривать массив слева до тех пор пока не обнаружим элемент a[i].k>x. После этого будем просматривать массив справа, пока не обнаружим a[j].k<x. Поменяем местами элементы a[i] и a[j] и продолжим такой процесс просмотра (слева и справа, обмен) пока оба просмотра не встретятся где-то внутри массива. В результате массив окажется разбитым на левую часть a[1..j], с ключами меньше (или равными) x и правую a[i..n], i=j+1, с ключами больше (или равными) x.
Алгоритм такого разделения очень прост и эффективен:
i:=1, j:=n; Листинг 3.8
Repeat
While a[i].k<x do i:=i+1;
While a[j].k>x do j:=j-1;
if i<=j then begin
w:=a[i];a[i]:=a[j];a[j]:=w;i:=i+1;j:=j-1 end
until i>j;
Чтобы отсортировать массив, остается применять алгоритм разделения к левой и правой частям, затем к частям частей, и так до тех пор, пока каждая из частей не будет состоять из одного единственного элемента. Алгоритм получается рекурсивным. На каждом этапе возникают две задачи по разделению. К решению одной из них можно приступить сразу, для другой следует заполнить начальные условия в список (номер разделения, границы и отложить ее решение до момента окончания сортировки выбранной половины. Требования из списка выполняются несколько специфическим образом, в обратном порядке (записанное последним выбирается первым). Такая организация списка записей называется стеком.
Рекурсивный вариант сортировки Хоара:
Листинг 3.9
Procedure QuickSortR(Var a:mas;n:word);
Procedure sort(L,R: word);