
- •Введение
- •Динамические структуры данных
- •Односвязные списки
- •Узлы связного списка
- •Создание односвязного списка
- •Вставка и удаление элементов в односвязном списке
- •Прохождение односвязного списка
- •Поиск предшествующего узла в односвязном списке
- •Вставка перед заданным узлом
- •Сортировка вставками
- •Примеры программ использующих односвязные списки
- •Демонстрационная программа для модуля Lists
- •Загрузка в список текстового файла
- •Задания к лабораторной работе
- •Вопросы к лабораторной работе
- •Справочные таблицы
- •Приложение А – Модуль Lists

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
Лабораторная работа №10 Динамические структуры данных. Односвязные списки.
Введение
В данной лабораторной работе рассмотрены односвязные списки. Дана структура для описания узлов односвязных списков. Рассмотрены основные алгоритмы работы со списками, такие как вставка и удаление узлов, поиск узлов, сортировка и др. Рассмотрен пример создания модуля для работы с односвязными списками. Рассмотрены некоторые примеры применения односвязных списков.
Динамические структуры данных
Динамическими структурами данных называют структуры данных размер и количество элементов которых может изменяться во время работы программы. Существует большое количество динамических структур данных. Примером таких структур могут служить списки и деревья. Рассмотрим одну из наиболее распространенных структур данных – списки.
Односвязные списки
Односвязный список представляет собой цепочку элементов, называемых узлами. При этом каждый элемент содержит указатель, указывающий на следующий элемент в этом списке.
n
Рисунок 1 – Узел односвязного списка
Для получения доступа ко всем элементам списка достаточно знать первый узел списка, от которого, путем переходов по ссылкам можно обойти все остальные узлы.
|
n |
|
|
|
n |
|
|
|
|
n |
|
|
nil |
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рисунок 2 – Односвязный список |
|
|
|
|
В отличие от массива узлы списка могут располагаться в различных участках памяти, а их порядок определяется ссылками. Таким образом размер списка ограничен лишь свободным объемом памяти. Недостатками списка является большое количество обращений к памяти при переборе элементов списка, как следствие, меньшее быстродействие при чтении списка. Достоинством списка является простота и высокая скорость вставки или удаления элемента из списка.
Конец списка обычно помечается пустым указателем nil или ссылка последнего узла указывает на первый узел, в этом случае список называется кольцевым.
n |
n |
n |
Рисунок 3 – Кольцевой односвязный список
Узлы связного списка
Описание узлов односвязного списка приведено ниже

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
//Описание структуры узла
type PNode=^TNode; //указатель на узел TNode=record
next:PNode; //указатель на следующий узел data:pointer;//указатель на данные узла end;
Узел может либо непосредственно содержать данные, либо содержать указатель на данные.
Для перехода по ссылке можно использовать примерно следующий код
var NextNode, CurrentNode:PNode; begin
...
NextNode:=CurrentNode^.next;
Создание односвязного списка
В самом простом случае первый узел в связном списке описывает весь список. Первый узел называют головой списка.
var HeadNode:PNode;
Если HeadNode содержит nil значит списка еще нет. Таким образом список создается следующим образом
var HeadNode:Pnode=nil;
Вставка и удаление элементов в односвязном списке
Для односвязного списка существует только один вариант вставки нового узла в список – вставкам после указанного узла списка. Пошаговый алгоритм вставки нового элемента в список приведен на рисунке 4

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
1) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n |
|
|
|
|
|
|
n |
|
|
|
|
|
|
|
|
|
n |
|
|
nil |
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n |
|
|
|
nil |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n |
|
|
|
|
|
|
|
n |
|
|
|
|
|
|
|
|
|
|
n |
|
|
|
nil |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n
3)
|
n |
|
|
|
n |
|
|
n |
|
nil |
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
n
Рисунок 4 – Вставка нового узла в односвязный список
Подпрограмма реализующая данный алгоритм может выглядеть следующим образом.
function InsertBefore(var ANode:PNode; InsNode:PNode):PNode; begin
//если список не содержит узлов if ANode=nil then ANode:=InsNode
else //если вставляемый узел не пустой if InsNode<>nil then
begin InsNode^.next:=ANode^.next; ANode^.next:=InsNode;
end;{if InsNode} Result:=InsNode;
end;{InsertBefore}
Обратите что существует особый случай – это вставка перед первым узлом списка. В этом случае первым элементом в списке становится вставляемый элемент. Так как односвязный список задается своим первым элементом, то код для этого случая надо писать отдельно, например
var MyList:PNode=nil; //список InsNode:PNode
begin
...
MyList:=InsertBefore(InsNode, MyList);
...

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
end.
Пошаговый алгоритм удаления узла из односвязного списка приведен на рисунке 5
1)
|
n |
|
|
|
n |
|
|
|
n |
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
2)
|
n |
|
|
|
n |
|
|
|
|
n |
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3)
|
n |
|
|
|
n |
|
|
|
|
n |
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nil
nil
nil
Рисунок 5 – Удаление узла из односвязного списка
Код удаления узла из списка может выглядеть следующим образом
function DeleteBefore(ANode:PNode):PNode; begin
if ANode<>nil then
if ANode^.next<>nil then //если удаляемый узел существует begin
Result:=ANode^.next;
ANode^.next:=ANode^.next^.next;
Result^.next:=nil; end{if ANode^.next}
else Result:=nil else Result:=nil; end;{DeleteBefore}
Здесь также существует особый случай, если удаляется первый элемент, он должен обрабатываться отдельно (не существует узел перед которым стоит первый узел), например так
var MyList:PNode=nil; //список Node:PNode
begin
...
Node:=MyList;
MyList:=MyList^.next;
Dispose(Node);
...
end.
Прохождение односвязного списка
Прохождение односвязного списка реализуется с помощью очень простого алгоритма: − вводится текущий узел;