- •4. Динамические структуры
- •4.1. Данные динамической структуры
- •4.2. Линейные связанные структуры данных
- •5.3.1. Создание лс.
- •5.3.2. Вывод списка
- •5.3.2. Удаление элемента из списка.
- •5.3.2. Вставка в отсортированный список.
- •5.3.3. Слияние двух отсортированных списков в третий отсортированный список.
- •5.4. Линейный двусвязный список.
- •5.4.1. Создание 2-связного списка.
- •5.4.2. Удаление в 2-связном списке.
- •5.4.2. Вставка заданного элемента в отсортированный 2-связный список.
- •5.5. Стек.
- •5.6. Пример вычисления арифметического выражения с помощью стеков.
4.2. Линейные связанные структуры данных
Для организации связей между элементами динамической структуры данных требуется, чтобы каждый элемент содержал кроме информационных значений как минимум один указатель. Отсюда следует, что в качестве элементов таких структур необходимо использовать записи, которые могут объединять в единое целое разнородные элементы. В простейшем случае элемент динамической структуры данных (узел) должен состоять из двух полей: информационного ( i ) и указательного ( L ). Соответствующие им объявления в Pascal будут иметь вид:
Type u = ^Uzl;
Uzl = Record
i :Integer;
L :u;
End;
Var h :u; { голова списка }
Правило: Тип указателя на элемент динамической структуры данных может и должен быть описан перед описанием типа этого элемента.
Схематично такую структуру данных можно показать следующим образом:
или в более простой форме, указывая только значения информационных полей:
Линейный список (ЛС) — это данные динамической структуры, которые представляют собой совокупность линейно связанных однородных элементов (узлов) и для которых разрешены следующие действия:
1) получить доступ к i-му узлу (читать, записать);
2) включить (вставить) новый узел перед i-м узлом;
3) удалить i-й узел;
4) объединить два (или более) списков в один список;
5) определить количество узлов в списке;
6) разбить список на два (или более) списков;
7) выполнить сортировку узлов по информационным полям узлов и т.п.;
Замечания.
1. На практике редко требуются все эти операции в самом общем виде.
2. Операции 1, 2, 3 для специальных случаев i=1 и i=n особо выделяются, поскольку проще получить доступ к первому и последнему узлам, чем к произвольному узлу.
3. Очень часто встречаются ЛС, в которых операции «включение», «исключение» и «получить доступ», почти всегда применяются к первому или последнему узлам. В этом смысле различают «стек», «очередь» и «дек» (см. ниже).
4. ЛС – структура с последовательным доступом, элементы которой связаны ссылками, поэтому операции вставки и удаления элементов сводятся к перекоммутации соответствующих ссылок между элементами.
Примеры работы с линейным списком приведены ниже.
5.3.1. Создание лс.
Исходные данные для информационных полей узлов считываются из текстового файла.
Procedure List (Var f :Text; Var h :u);
Var t :u;
Begin Reset(f); New(h); Read ( f, h^.i ); {создали первый узел}
t:=h; {t – указатель на текущий узел, вначале указывает на первый }
While Not Eof( f ) Do Begin
New( t^.L); {создали новый узел и подключили его к предыдущему узлу}
t:=t^.L; {перешли на новый узел и
Read(f, t^.i); заполнили его информационную часть}
End;
t^.L:=Nil; {ссылка из последнего узла равна Nil}
Close(f);
End;
Более изящно выглядит рекурсивный вариант создания списка.
Function ListR ( k :Integer) :u;
Var t :u;
Begin
If k=0 Then ListR:=Nil {ссылочное поле последнего узла есть Nil }
Else Begin {создание очередного узла}
New(t); Read ( f, t^.i ); {создали новый узел и
t^.L := ListR (k - 1); подключили его к следующему узлу}
ListR:=t;
End;
End;
Вызов: ….. h:=ListR(FileSize(f)); …..