Добавил:
ikot.chulakov@gmail.com Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы по Delphi с готовыми программами / Лабораторная работа №10 Односвязные списки, Поиск, Сортировка.pdf
Скачиваний:
28
Добавлен:
12.07.2020
Размер:
260.42 Кб
Скачать

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»

Лабораторная работа №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.

Прохождение односвязного списка

Прохождение односвязного списка реализуется с помощью очень простого алгоритма: вводится текущий узел;