
- •Теоретический раздел лекции Тема 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. Индивидуальные задания
- •Курсовая работа
- •Литература
Inherited create;
sp1:=nil; spk:=nil;
end;
. . . . . . . . . . . . .
Var stec,st1,turn,tr1:Tlist; inf:Tinf;
Begin
stec:=Tlist.create;
stec.Add1(inf);
stec.print;
. . . . . . .
stec.free;
Ниже приведены наиболее часто используемые методы данного класса для работы со списком.
4.4. Начальное формирование, добавление и удаление элементов однонаправленного списка
Обработку связанных списков удобно производить на основе набора стандартных методов класса, оформленных в отдельный модуль. Интерфейсная часть модуля, как минимум, содержит описание вышерассмотренного класса.
Добавление новой записи в конец списка с двумя точками доступа sp1, spk осуществляется следующей процедурой:
Листинг 4.5
Procedure Tlist.Addk(Inf:TInf);
begin
if spk=Nil then begin // если список пуст
New(spk);
spk^.A:=Nil;
spk^.Inf:=inf;
sp1:=spk;//если очередь
end;
else begin
New(spk^.A);//вместо Nil в адресную часть последней записи //помещается выделенный новый адрес
spk:=spk^.A;//этот адрес запоминается также в spk
spk^.Inf:=Inf;
spk^.A:=Nil;end;
end;
В результате первого обращения к этой подпрограмме (если sp1=spk=Nil) в списке размещается одна заявка. При этом инициируются и в дальнейшем поддерживаются два указателя sp1 - адрес 1-й записи, spk - адрес последнeй.
Добавление новой записи в начало списка:
Листинг 4.6
Procedure Tlist.Add1(Inf:TInf);
begin
if sp1=Nil then begin // если список пуст
New(sp1);
sp1^A:=Nil;
sp1^.Inf:=Inf;
spk:=sp1;//если очередь
end;
else
begin
New(sp);
sp^.Inf:=Inf;
sp^.A:=sp1;
sp1:=sp;
end;
end;
Заметим, что оператор if в этой процедуре используется только для поддержания работы списка с двумя точками входа. Поэтому при работе со стеком, имеющим только одну точку входа sp1 переменную spk и оператор if в этой процедуре можо убрать и назвать метод, например Addst.
Прочесть и стереть информацию из начальной записи списка можно с помощью следующей процедуры:
Листинг 4.7
Procedure Tlist.Reаd1(var Inf:Tinf);
begin if sp1<>Nil then begin
Inf:=sp1^.Inf;
sp:=sp1;
sp1:=sp1^.A;
if sp1=Nil then spk:=Nil;
Dispose(sp);
end end;
здесь второй оператор if необходим для поддержания очереди, поэтому при работе со стеком этот оператор if можно убрать и назвать метод Readst.
Чтение и стирание последней записи из списка:
Листинг 4.8
Procedure Tlist.Reаdk(var Inf:Tinf);
Begin
If spk<>Nil then begin
Inf:=spk.Inf;
if sp1=spk then //если запись только одна
begin Dispose(spk); sp1:=Nil; spk:=Nil end
else begin
sp:=sp1;//поиск предпоследней записи:
while sp^.A<>Spk do sp:=sp^.A;
Dispose(spk);//освобождение памяти
spk:=sp;//запись адреса предпоследней записи
spk^.A:=Nil;
end end;
end;
Как видим, удаление последней записи в рассматриваемом однонаправленном списке значительно сложнее, чем первой. Поэтому при работе с очередью добавление новой записи производится в конец списка (Addk) а удаление из начала (Read1). При работе со стеком добавление и чтение записей производят через начальный адрес sp1.
Распечатать текущий список можно, используя следующую процедуру:
Листинг 4.8
Procedure Tlist.Print;
begin
sp:=sp1;
While sp <> Nil do
begin
Writeln(sp^.Inf);
sp:=sp^.A;
end;
end;
Эту процедуру легко модифицировать для поиска нужного элемента, подсчета количества элементов.
Чтение и удаление элемента из середины однонаправленного списка сделать просто, если известен адрес ячейки spi находящейся перед удаляемой:
Листинг 4.9
Procedure Tlist.ReadAfter(spi:Psel;var Inf:TInf);
begin
sp:=spi^.A;//в sp адрес следующей за spi
Inf:=sp^.Inf;
spi^.A:=sp^.A;
Dispose(sp);
end;
Добавление элемента в середину однонаправленного списка послеэмента с адресом spi:
Листинг 4.10
Procedure Tlist.AddAfter(spi:Psel,Inf:TInf);
begin
New(sp);
sp^.Inf:=Inf;
sp^.A:=spi^.A;
spi^.A:=sp;
end;
Чтение и удаление ячейки с адресом spi из списка, и добавление в список ячейки перед spi осуществляется более сложно, с использованием ReadAfter; АddAfter и дополнительного копирования информационной ячейки:
Листинг 4.11
Procedure Tlist.Readspi(spi:Psel;var Inf:TInf);
begin
Inf:=spi^.Inf;
RedAfter(spi,spi^.Inf);//читаем и удаляем след. за spi
end;
Procedure Tlist.AddBefore(spi:Psel;Inf:Tinf);
begin
AddAfter(spi,spi^.Inf);//вставляем spi после spi
spi^.Inf:=Inf;
end;
Используя приведенные выше процедуры, нетрудно составить программы по формированию и обслуживанию всевозможных однонаправленных списков.