
- •Тема 1. Стеки, очереди, деки 7
- •Тема 2. Односвязные и двусвязные линейные списки 21
- •Тема 3. Бинарные деревья 40
- •Тема 4. Графы 65
- •Введение
- •Терминология
- •Классификация структур данных по различным признакам
- •Типовые операции над структурами данных
- •Эффективность алгоритмов. O-обозначения
- •Тема 1. Стеки, очереди, деки
- •Операции над стеком
- •Реализация стека
- •Реализация основных операций над стеком
- •Использование стека для преобразования форм записи выражений.
- •Очередь
- •Операции над очередью
- •Операции над деком
- •Реализация очереди и дека
- •Реализация основных операций над очередью и деком
- •Итератор
- •Лабораторная работа 1. Стеки, очереди, деки
- •Тема 2. Односвязные и двусвязные линейные списки
- •Линейный список
- •Операции над линейным списком
- •Реализация линейного списка в виде односвязной динамической структуры
- •Реализация основных операций над односвязным списком
- •Циклический список
- •Операции над циклическим списком
- •Односвязная реализация циклического списка
- •Реализация основных операций над односвязным циклическим списком
- •Реализация линейного списка в виде двусвязной динамической структуры
- •Реализация основных операций над двусвязным списком
- •Циклический двусвязный список
- •Реализация основных операций над двусвязным циклическим списком
- •Лабораторная работа 2. Односвязные и двусвязные линейные списки
- •Тема 3. Бинарные деревья
- •Основные понятия и определения
- •Построение бинарного дерева
- •Операции над бинарным деревом
- •Реализация бинарного дерева
- •Реализация основных операций над бинарным деревом
- •Дерево выражения
- •Дерево поиска
- •Операции над деревом поиска
- •Реализация дерева поиска
- •Реализация операций над деревом поиска
- •Сбалансированные деревья
- •Включение в сбалансированное дерево
- •Лабораторная работа 3. Бинарные деревья
- •Тема 4. Графы
- •Основные понятия и определения
- •Граф g7
- •Операции над графом
- •Реализация графа
- •Реализация основных операций над ориентированным графом
- •Обход ориентированного графа
- •Вычисление расстояния между узлами ориентированного графа
- •Лабораторная работа 4. Ориентированные графы
- •Библиографический список
-
Реализация основных операций над односвязным списком
Включение элемента со значением v после элемента с адресом Addr:
Реализация операции приведена ниже. Предполагается, что адрес Addr отличен от nil и элемент с адресом Addr присутствует в списке (эти ситуации должны быть проверены в вызывающей программе). Если список пуст, то новый элемент включается в начало списка.
procedure tList.InsertAfter(Addr: pItem; v: tValue);
var
NewItem: pItem; // вспомогательный указатель на новый элемент
begin
NewItem:= New(pItem); // выделение памяти под новый элемент списка
NewItem^.Value:= v;
if Empty
then begin // если список пуст, включаем в его начало
NewItem^.Next:= nil;
fHead:= NewItem;
end
else begin // список не пуст - включаем после элемента с адресом Addr
NewItem^.Next:= Addr^.Next;
Addr^.Next:= NewItem;
end;
Inc(fSize); // увеличение числа элементов списка на 1
end; // procedure tList.InsertAfter
Включение элемента со значением v в список перед элементом с адресом Addr может быть выполнено следующим образом. Сначала новый элемент включается после элемента с адресом Addr, а затем происходит обмен содержательными полями между включенным элементом и элементом с адресом Addr. Предполагается, что адрес Addr отличен от nil, и элемент с адресом Addr присутствует в списке. Если список пуст, то новый элемент включается в начало списка.
procedure tList.InsertBefore(Addr: pItem; v: tValue);
var
NewItem: pItem; // вспомогательный указатель на новый элемент
begin
NewItem:= New(pItem); // выделение памяти под новый элемент списка
if Empty
then begin // если список пуст, включаем в его начало
NewItem^.Value:= v;
NewItem^.Next:= nil;
fHead:= NewItem;
end
else begin // иначе обмен содержимым элементов NewItem^ и Addr^
NewItem^:= Addr^;
Addr^.Value:= v;
Addr^.Next:= NewItem;
end;
Inc(fSize); // увеличение числа элементов списка на 1
end; // procedure tList.InsertBefore
Исключение элемента, следующего за элементом с адресом Addr:
function tList.DeleteAfter(Addr: pItem): tValue;
var
DisItem: pItem; // вспомогательный указатель на исключаемый элемент
begin
if Addr^.Next=nil
then begin
WriteLn('Исключаемый элемент отсутствует');
Halt;
end
else begin
DisItem:= Addr^.Next;
DeleteAfter:= DisItem^.Value;
Addr^.Next:= DisItem^.Next;
Dispose(DisItem);
end;
Dec(fSize); // уменьшение числа элементов списка на 1
end; // function tList.DeleteAfter
Исключение из списка элемента с указателем Addr. В этом случае необходимо определить адрес элемента, предшествующего исключаемому, что выполняется проходом по списку от его начала с помощью передвигаемого по элементам списка вспомогательного указателя Item типа pItem.
function tList.Delete(Addr:pItem): tValue;
var
Item: pItem; // вспомогательный указатель на элемент списка
begin
if Addr=fHead
then begin // исключается первый элемент
Delete:= Addr^.Value;
fHead:= Addr^.Next;
Dispose(Addr);
end
else begin // поиск элемента, предшествующего исключаемому
Item:= fHead;
while (Item^.Next<>Addr) and (Item<>nil) do Item:= Item^.Next;
if Item=nil
then WriteLn('Исключаемый элемент отсутствует')
else begin
Delete:= Addr^.Value;
Item^.Next:= Addr^.Next;
Dispose(Addr);
end;
end;
Dec(fSize); // уменьшение числа элементов списка на 1
end; // function tList.Delete
Операции tList.DeleteAfter и tList.Delete исключения элементов из списка неприменимы к пустому списку, поэтому перед их выполнением необходимо анализировать значение признака «список пуст». При выполнении этих операций предполагается, что заданный адрес Addr отличен от nil, и элемент с заданным адресом присутствует в списке.
Поиск элемента с заданным значением v в списке:
function tList.Search(v: tValue): pItem;
// Возвращение адреса элемента со значением v
// или nil, если элемент отсутствует
var
Item: pItem;
begin
if Empty
then Search:=nil
else begin
Item:= fHead;
while (Item^.Next<>nil) and (Item^.Value<>v) do Item:= Item^.Next;
if Item^.Value=v then Search:= Item else Search:=nil;
end;
end; // function tList.Search
Включение элемента со значением v в начало списка:
procedure tList.InsertHead(v: tValue);
var
NewItem: pItem; // указатель на новый элемент
begin
NewItem:= New(pItem); // выделение памяти под новый элемент
NewItem^.Value:= v; // запись v в поле значения нового элемента
NewItem^.Next:= fHead; // fHead -> в поле ссылки нового элемента
fHead:= NewItem; // перемещение fHead на новый элемент
Inc(fSize); // увеличение числа элементов списка на 1
end; // procedure tList.InsertHead
Включение элемента со значением v в конец списка:
procedure tList.InsertRear(v: tValue);
var
Item: pItem; // указатель на последний элемент
begin
if Empty
then InsertHead(v) // если список пуст, то включение в начало,
else begin // иначе поиск адреса последнего элемента
Item:= fHead;
while Item^.Next<>nil do Item:= Item^.Next;
InsertAfter(Item, v); // и вставка после последнего элемента
end;
end; // procedure tList.InsertRear
Исключение элемента из начала списка:
function tList.DeleteHead: tValue;
begin
DeleteHead:= Delete(fHead)
end; // function tList.DeleteHead
Исключение элемента из конца списка:
function tList.DeleteRear: tValue;
var
Item:pItem;
begin
Item:= fHead;
while Item^.Next<>nil do Item:= Item^.Next;
DeleteRear:= Delete(Item)
end; // function tList.DeleteRear