- •Структуры и алгоритмы обработки данных
- •Часть 1
- •Последовательное представление линейных списков
- •Связанное представление линейных списков
- •Очередь
- •Связанное представление матриц
- •Бинарное дерево поиска. Построение и поиск элемента
- •Бинарное дерево поиска. Удаление элемента
- •Линейные списки с индексами. Построение и поиск элемента. Способы коррекции
- •Инвертированные списки
- •Построение словаря с использованием деревьев
- •Построение словаря с использованием матриц
Очередь
First In First Out (FIFO). Заранее выделяется память из N-последовательных ячеек. Существуют два индекса:
HEAD – номер первого элемента очереди;
TAIL – последний элемент очереди.
Структура очереди:
Заказ, поступающий в очередь первым, выбирается первым для обслуживания. Пользователю доступны начало и конец очереди. Начало – позиция, из которой выбирается элемент. Конец – позиция, в которую помещается заносимый в очередь элемент.
Алгоритм постановки элемента в очередь:
Если TAIL=0 и HEAD=0, то очередь пуста. TAIL:=TAIL+1; Q(TAIL):=X; HEAD:=1. Если TAIL<>0, то очередь уже существует. TAIL=(TAIL+1)mod N. Если при этом TAIL=HEAD, то очередь переполнена. Q(TAIL):=X
Выбор элемента из очереди:
Если TAIL=0 и HEAD=0, то очередь пуста. Если очередь не пуста, то Y:=Q(HEAD); HEAD:=(HEAD+1)mod N.
Связанное представление очереди:
X1
X2
XN X
Если head=nil, то очередь пуста
y:=head^.info;
head:=head^.link;
Постановка элемента в очередь:
Если очередь пуста, то вставляемый элемент будет первым.
-
p:=head;
dispose(p);
new(p);
head:=p;
tail:=p;
p^.info:=x;
p^.link:=nil;
new(p);
p^.info:=x;
p^.link:=nil;
tail^.link:=p;
tail:=p;
Стек
Last In First Out (LIFO). Существует индекс TOP – последний элемент стека.
Структура стека:
Доступна только вершина стека. Вершина стека – это позиция, в которой находится последний по времени поступления элемент. Выбирать элемент можно только из вершины стека. Выбранный элемент исключается из стека, а в его вершине оказывается элемент, который был занесен в стек перед выбранным элементом.
Алгоритм записи элемента в стек:
Если TOP=0, то стек пуст. TOP:=TOP+1. Если TOP>N, то стек переполнен. S(TOP):=X.
Алгоритм выбора элемента из стека:
Если TOP=0, то стек пуст. Y:=S(TOP); TOP:=TOP – 1.
Связанное представление стека:
X1 X
X2
XN
TOP
Запись элемента в стек:
Если очередь пуста, то вставляемый элемент будет первым.
Внесение элемента в стек:
procedure InStack(var st: point; a: value);
var
q: point;
begin
new(q);
q^.inf:=a;
q^.next:=st;
st:=q;
end;
Выбор элемента из стека:
procedure OutStack(var st: point; var a: value);
var
q: point;
begin
if st=nil then writeln(‘Стек пуст’)
else
begin
a:=st^.inf;
q:=st;
st:=st^.next;
dispose(q);
end;
end;
Связанное представление матриц
Рассмотрим такую структуру данных, как двунаправленный список.
Предположим, что задана матрица A(N×M), где N - количество строк, M - количество столбцов.
-
А11
А12
А13
А21
А22
А23
В памяти матрица описывается либо построчно, либо по столбцам, но чаще всего применяется построчное описание.
Существует связанное представление матриц. Если в двумерном списке содержится много пустых значений или нулей, то их удобно хранить в виде связанного представления.
-
i
j
Аij
LINKD
LINKR
type
link=^node;
node=record
i: integer;
j: integer;
pole: integer;
linkd: link;
linkr: link
end;
Операции, производимые над матрицами: сложение, перемножение, транспонирование. Разумеется, эти операции удобнее выполнять над последовательными списками.
Рассмотрим для примера линейный однонаправленный список.
На рис.1 приведена структура однонаправленного списка. На нем поле INF – информационное поле, NEXT – указатель на следующий элемент списка. Список имеет особый элемент head, называемый указателем начала списка или головой списка, который обычно по формату отличен от остальных элементов. В поле указателя последнего элемента списка находится специальный признак nil, свидетельствующий о конце списка.
Рис.1
Элемент ЛОС имеет следующую структуру:
type
point = ^element; { указатель в списке }
element = record { элемент списка }
inf:integer;{ информационная часть }
next:point; {указатель на следующий элемент}
end;
Алгоритм вставки:
Вставка производится в конец списка. Для этого необходимо пройти весь список:
Если список пустой: if p=nil then
Тогда создаём новый указатель на начало списка – head, и присваиваем информационному полю введённое число, а ссылке на следующий элемент – nil:
new(head);
head^.inf:=key;
head^.next:=nil
Если список не пустой, то перебираем все элементы списка пока поле next<>nil:
while p^.next<>nil do p:=p^.next;
Создаём новый указатель, указателю на следующий элемент присваиваем nil, а в последнем элементе списка в поле next записываем адрес нового указателя.
new(r);
r^.inf:=key;
r^.next:=nil;
p^.next:=r
Алгоритм поиска:
Поиск производится перебором всех элементов ЛОС до тех пор, пока не будет найден элемент или пока не конец списка:while(p<>nil) or (p^.inf<>key) do p:=p^.next
Алгоритм удаления:
Удаление так же производится перебором всех элементов ЛОС. Удаляются все одинаковые элементы. Если удаляемый элемент первый в списке то указателю head присваивается значение поля next, а сам элемент удаляется:
head:=p^.next;
dispose(p);
Если элемент не первый то полю next предыдущего элемента присваивается значение поля next удаляемого элемента, а сам элемент удаляется:
if q^.inf=key then
p^.next:=q^.next;{p-предыдущий элемент}
dispose(q);