- •Введение
- •Машинное представление связных линейных списков
- •Структура односвязного списка
- •Структура двухсвязного списка
- •Структура кольцевого двухсвязного списка
- •Реализация операций над связными линейными списками
- •Вставка элемента в список.
- •Вставка элемента в середину 1-связного списка
- •Перестановка элементов списка.
- •Копирование части списка.
- •Слияние двух списков.
- •Применение линейных списков
- •5.3. Мультисписки
- •Нелинейные разветвленные списки Основные понятия
- •Представление списковых структур в памяти.
- •. Операции обработки списков
Перестановка элементов списка.
Изменчивость динамических структур данных предполагает не только изменения размера структуры, но и изменения связей между элементами. Для связных структур изменение связей не требует пересылки данных в памяти, а только изменения указателей в элементах связной структуры. В качестве примера приведена перестановка двух соседних элементов списка. В алгоритме перестановки в односвязном списке исходили из того, что известен адрес элемента, предшествующего паре, в которой производится перестановка. В приведенном алгоритме также не учитывается случай перестановки первого и второго элементов.
{==== Программный пример ====}
{ Перестановка двух соседних элементов в 1-связном списке }
Procedure ExchangeSll(
prev : sllptr { указатель на эл-т, предшествующий
переставляемой паре } );
var p1, p2 : sllptr; { указатели на эл-ты пары }
begin
p1:=prev^.next; { указатель на 1-й эл-т пары }
p2:=p1^.next; { указатель на 2-й эл-т пары }
p1^.next:=p2^.next; { 1-й элемент пары теперь указывает на
следующий за парой }
p2^.next:=p1; { 1-й эл-т пары теперь следует за 2-ым }
prev^.next:=p2; { 2-й эл-т пары теперь становится 1-ым }
end;
В процедуре перестановки для двухсвязного списка (рис.5.10.) нетрудно учесть и перестановку в начале/конце списка.
Копирование части списка.
При копировании исходный список сохраняется в памяти, и создается новый список. Информационные поля элементов нового списка содержат те же данные, что и в элементах старого списка, но поля связок в новом списке совершенно другие, поскольку элементы нового списка расположены по другим адресам в памяти. Существенно, что операция копирования предполагает дублирование данных в памяти. Если после создания копии будут изменены данные в исходном списке, то изменение не будет отражено в копии и наоборот.
Копирование для односвязного списка показано в программном примере.
{==== Программный пример ====}
{ Копирование части 1-связного списка. head - указатель на
начало копируемой части; num - число эл-тов. Ф-ция возвращает
указатель на список-копию }
Function CopySll ( head : sllptr; num : integer) : sllptr;
var cur, head2, cur2, prev2 : sllptr;
begin
if head=nil then { исходный список пуст - копия пуста }
CopySll:=nil
else begin
cur:=head; prev2:=nil;
{ перебор исходного списка до конца или по счетчику num }
while (num>0) and (cur<>nil) do begin
{ выделение памяти для эл-та выходного списка и запись в него
информационной части }
New(cur2); cur2^.inf:=cur^.inf;
{ если 1-й эл-т выходного списка - запоминается указатель на
начало, иначе - записывается указатель в предыдущий элемент }
if prev2<>nil then prev2^.next:=cur2 else head2:=cur2;
prev2:=cur2; { текущий эл-т становится предыдущим }
cur:=cur^.next; { продвижение по исходному списку }
num:=num-1; { подсчет эл-тов }
end;
cur2^.next:=nil; { пустой указатель - в последний эл-т
выходного списка }
CopySll:=head2; { вернуть указатель на начало вых.списка }
end; end;