Научная статья на тему 'Основные алгоритмы работы с линейными цепными списками'

Основные алгоритмы работы с линейными цепными списками Текст научной статьи по специальности «Математика»

CC BY
511
36
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
СПИСКИ / ПОИСК ЭЛЕМЕНТА / СОРТРОВКА СПИСКА / СЛИЯНИЕ СПИСКОВ

Аннотация научной статьи по математике, автор научной работы — Дмитриева Марина Валерьевна

В статье рассматриваются основные алгоритмы работы со списками: поиск в списке элемента с заданным информационным полем, сортировка списка и слияние двух упорядоченных списков. Эти алгоритмы используются при решении более сложных задач.

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

Текст научной работы на тему «Основные алгоритмы работы с линейными цепными списками»

Дмитриева Марина Валерьевна

ОСНОВНЫЕ АЛГОРИТМЫ РАБОТЫ С ЛИНЕЙНЫМИ ЦЕПНЫМИ СПИСКАМИ

При создании любой сложной структуры данных надо уметь решать задачи поиска, то есть определять, принадлежит ли некоторый элемент построенному множеству элементов. Применительно к списку задача поиска конкретизируется следующим образом: требуется определить, имеется ли в списке элемент, информационное поле которого совпадает с заданным значением (образцом).

Возможны два варианта ответа на вопрос, найден ли элемент в списке. В первом случае можно выдавать логическое значение true, если элемент найден, и false в противном случае. Во втором варианте в качестве ответа может быть ссылка на найден-

|| ¡<

срме&ь ремлЛл j&pazu плиосл,,,

ный элемент или значение Nil, если элемента в списке не обнаружено.

При описании процедур работы со списками будем считать, что определены структуры данных, представленные в листинге 1.

ПОИСК ЭЛЕМЕНТА В СПИСКЕ.

ВАРИАНТ 1

Пусть задан линейный список с указателем t на первый элемент. Требуется определить, есть ли в списке элемент с заданным значением r информационного поля.

Указатель cur устанавливается на текущий элемент, в начальный элемент он совпадает с t. Для поиска элемента в линейном списке поступаем следующим образом. Сравниваем значение информационного поля текущего элемента со значением r. Если значения совпадают, то задача решена, в противном случае требуется перейти к следующему элементу списка.

Процесс просмотра элементов списка продолжается до тех пор, пока не будет найден соответствующий элемент, либо пока не исчерпается весь список. В последнем случае нужного элемента в списке нет.

Листинг 1. Описание структур данных для работы с линейными списками

type

elem_list = integer; {тип информационного поля элемента списка} list = Aelem; (указатель на элемент списка)

elem= record info: elem_list; (информационное поле элемента списка) next: list {указатель на следующий элемент}

end;

Дмитриева M.B.

Рис. 1. Поиск элемента в списке

Функция, осуществляющая поиск элемента в линейном списке, приведена в листинге 2. Функция выдает значение true, если элемент найден, и false в противном случае.

На рис. 1 изображена ситуация в точке {1}, которую можно описать так: просмотрен линейный список до элемента, предшествующего элементу, на который установлен указатель cur. Среди просмотренных элементов нет элемента с заданным информационным полем (равного образцу).

Указатель cur установлен на первый элемент непросмотренной части списка. В точке {1} верно и следующее утверждение: не про-

'Ироцесс afeocMO&fia с*иижа...

смотренная часть списка не пуста. Точка {2} соответствует тому, что цикл завершил свою работу, значение переменной cur равно nil, список просмотрен полностью, элемент не найден.

ПОИСК ЭЛЕМЕНТА В СПИСКЕ.

ВАРИАНТ 2

Приведем еще один вариант описания функции поиска элемента в линейном списке, использующий особенности структур данных языка Паскаль. Описание функции приведено в листинге 3.

Листинг 2. Поиск элемента в списке. Вариант 1

function searchl (var t: list; r: elem list): boolean;

var cur: list;

begin searchl := false;

cur := t;

while cur <> nil do {1}

if curA.info = r

then

begin searchl := true; exit end

else cur := curA.next {2}

end

Листинг 3. Поиск элемента в списке. Вариант 2

Function search2 (var t: list; r: elem_list): boolean;

var cur: list; sel: Boolean; begin sel := false; cur := t;

while sel < (cur <> nil) do begin sel := curA.info = r; cur := curA.next

end; search2 := sel

end

sel < (cur <> nil) также станет равным false, и цикл завершит свою работу.

Если же просмотрен весь список и в нем нет элемента с информационным полем r, то значение переменной sel равно false, значение выражения cur<>nil после просмотра всего списка равно false. Формула false < false имеет значение false, поэтому работа цикла будет завершена. Результат поиска совпадает со значением переменной sel.

СОРТИРОВКА СПИСКА

...алгари&м сор&ироёки миЛейЛага списка á oopfrfKe áofjíac&aftu#....

Напомним, что стандартный тип Boolean считается перечислимым типом, определенным следующим образом: type Boolean = (false, true). Так как

элементы в перечислимом типе считаются упорядоченными, то верно соотношение false < true. Тело цикла выполняется, если истинно выражение sel < (cur <> nil).

Если в списке найден элемент с информационным полем r, то значение логической переменной sel станет равным true в результате выполнения оператора присваивания sel: =curA. info=r. Так как значение выражения true < L ложно при любом значении логической переменной L, то выражение, управляющее работой цикла

Предположим, что на элементах, из которых строится список, задано отношение порядка. Рассмотрим алгоритм сортировки линейного списка в порядке возрастания значений информационных полей его элементов.

Пусть список задан указателем на первый элемент ^ Будем использовать два указателя р и д, указатель р устанавливается на очередной элемент списка, указатель д пробегает значения от элемента, непосредственно следующего за тем, на который установлен указатель р, до конца списка.

Сравниваются информационные поля элементов и s2), на которые установлены указатели р и д. Если верно, что s1 > s2, то информационные поля меня-

Листинг 4. Сортировка списка в порядке возрастания информационных полей

procedure sort_list (var t: list);

var p,q: list; r: elem list;

begin p:=t;

while p <> nil do

begin

q:= pA- next;

while q <> nil do

begin if pA.info > qA.info

then

begin

r := pA.info;

pA.info := qA.info;

qA.info :=r

end;

q := qA.next

end;

p := pA .next {1}

end

end

Дмитриева М.В.

Рис. 2. Сортировка элементов списка в порядке возрастания

ются местами. После того, как для фиксированного р переменная д пробежит значения до конца списка, элемент, на который указывает р, имеет информационное поле, наименьшее из всех информационных полей следующих за ним элементов.

Дальнейшие действия состоят в том, чтобы перейти к следующему за р (если он есть) элементу списка и для него повторить: установить указатель д на следующий за р элемент и сравнить информационные поля элемента, на который установлен указатель р, и всех следующих за ним элементов.

Если просмотрен весь список, то анализ списка завершен и элементы списка упорядочены. До начала просмотра списка значение р совпадает с Ъ, указатель д установлен на второй элемент списка, если список содержит более одного элемента. Процедура, осуществляющая сортировку элементов списка в порядке возрастания информационных полей, приведена в листинге 4.

На рис. 2 представлена ситуация, когда список, предшествующий элементу, на который установлен указатель р, уже отсортирован, указатель д установлен на эле-

мент, непосредственно следующий за p. После того как указатель q «пробежит» по всем элементам «хвоста» списка, элемент, на который установлен указатель p, будет иметь наименьшее значение информационного поля из всех элементов «хвоста» списка.

После перехода к следующему элементу списка в точке {1} просмотренная часть списка (начало списка) отсортирована. Значение p, равное nil, будет означать, что просмотрен весь список и его элементы расположены в порядке возрастания.

СЛИЯНИЕ ДВУХ УПОРЯДОЧЕННЫХ СПИСКОВ

Рассмотрим два упорядоченных списка. Задача слияния двух упорядоченных списков состоит в формировании упорядоченного списка, состоящего из тех же элементов, что и исходные. Результирующий список должен быть упорядоченным.

Для решения задачи будем параллельно просматривать два списка с указателями t и p. Пусть t1 - указатель на первый элемент непросмотренной части первого списка, указатель pi устанавливается на текущий элемент второго списка. В начальный момент времени оба указателя установлены на первые элементы списков (если списки не пусты).

Все просмотренные элементы хранятся в списке с указателем на первый элемент s, указатель si установлен на последний элемент построенного (уже слитого) списка. Естественно, сначала формируемый список пуст. Сравниваем информационные поля

Рис. 3. Слияние двух упорядоченных списков

SafAM

ух ymftflfmefrfrux

Листинг 5. Процедура слияния двух упорядоченных списков

procedure sl_list (var t, p, s: list);

var tl, pi, s1: list;

begin if t = nil then s := p else if p= nil then s := t

else {оба списка не пусты}

begin

tl := t; pi := p;

if tiA.info < piA.info

then begin s := tl; tl := tiA.next end

else begin s := pi; pi := piA.next end;

si:=s;

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

while (ti <> nil) and (pi <> nil) do

begin if tiA.info < piA.info

then begin siA.next :=ti; ti := tiA.next end

else begin siA.next :=pi; pi := piA.next end;

si:=siA.next

end

end

end

элементов, на которые установлены указатели и р1.

Тот элемент, информационное поле которого меньше, добавляется в конец формируемого списка, а указатель в соответствующем списке сдвигается на следующий элемент списка.

Просмотр списков следует продолжать до тех пор, пока не исчерпается один из списков. Процедура слияния двух упорядоченных списков приведена в листинге 5.

На рис. 3 изображена ситуация, когда просмотрены элементы первого списка до элемента с указателем Ъ1, просмотрены элементы второго списка до элемента с указателем р1, просмотренные части обоих списков «слиты», указатель б установлен на первый элемент списка-результата, указатель б1 установлен на последний элемент формируемого списка.

Просмотр списков продолжается, пока не исчерпается один из них. Не просмотренная часть другого списка составляет «хвост» списка результата.

Дмитриева Марина Валерьевна, доцент кафедры информатики математико-механического факультета Санкт-Петербургского государственного университета.

ЗАДАЧИ

1. Опишите функцию, которая определяет число элементов в списке, информационные поля которых совпадают с заданным значением.

2. Опишите функцию, которая проверяет, имеются ли в списке элементы, непосредственно следующие друг за другом, информационные поля которых одинаковы.

3. Опишите функцию, которая определяет, образуют ли элементы списка возрастающую последовательность.

4. Опишите следующую модификацию рассмотренной процедуры сортировки линейного списка. При каждом фиксированном значении р определите указатель на элемент с минимальным значением информационного поля для элементов, следующих за Р, и лишь затем в случае необходимости меняйте значения информационных полей.

5. Опишите процедуру слияния двух упорядоченных списков, исходные списки должны остаться без изменения.

Наши авторы. 2007 Our authors, 2007

i Надоели баннеры? Вы всегда можете отключить рекламу.