Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика 2013.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
839.17 Кб
Скачать

13. Линейные динамические информационные структуры. Их моделирование средствами языка Паскаль.

Пусть D – множество, состоящее из элементов D={d1,d2,…,dn} – множество элементов данных и пусть R={r1,r2,…,rn} – множество отношений, заданных на D, тогда S=<D,R> называется информационной структурой (структурой данных).

Элементы данных, входящие в состав информационной структуры принято называть узлами информационной структуры (это d1,d1,…,dn).

Различают статические и динамические информационные структуры.

В статических информационных структурах количество и состав узлом не меняется в течении всего времени существования информационной структуры.

В динамических информационных системах количество и состав узлов могут меняться.

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

Стек – это ЛДИС, доступ к элементам которой организован по принципу ЛИФО. Как и для любой другой динамической информационной системы, для стека определяются операции: добавить элемент (узел) к стеку, извлечь из стека, а также операции инициализации стека и проверки стека на пустоту. Элемент, который добавлен в стек последним, называется верхушкой стека, элемент, помещенный в стек первым называется дном стека. Верхушку и дно стека называют также соответствующие позиции. При извлечении элемента из стека доступен только верхушечный элемент. Операция извлечения элемента из стека определена не всегда, а только для непустого стека. Логически, стек является хранилищем информации с бесконечным объемом. Однако, на практике, в силу ограниченности ресурсов компьютера реализуются так называемые ограниченные стеки, для которых фиксировано максимальное количество хранящихся в стеке элементов. Очевидно, что для ограниченных стеков операция добавления в стек также определена не всегда. Ситуация, в которой стек заполнен полностью и делается попытка добавления еще одного элемента называется переполнением. В алгоритмах, использующих стеки, обычно ситуация переполнения рассматривается как ошибка, после которых дальнейшая обработка данных невозможна. В тоже время состояние пустого стека является допустимым и обычно лишь «сигнализирует» о проявлении определенных свойств обрабатываемых данных.

Очередь – это ЛДИС, организованная по принципу ФИФО. Абстрактная очередь, как и стек является бесконечным по объему хранилищем информации, однако на практике реализуют ограниченные очереди (с фиксированным максимальным количеством элементов). Для очередей, как и для стеков, определены операции: добавить в очередь, удалить из очереди, инициализировать очередь и проверить очередь на пустоту.

Дек (двусторонняя очередь) – это ЛДИС с двумя входами и двумя выходами, т.е. для нее определены операции: добавить справа, извлечь справа, добавить слева, извлечь слева. Очевидно, что, если ограничить возможности применения некоторых из указанных 4 операций, то в частных случаях получим стек или очередь.

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

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

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

Реализация ЛДИС.

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

Модель стека содержит информационную составляющую и операционную составляющую. Информационная составляющая может быть представлена некоторым массивом S и переменной, указывающей на верхушку стека. В качестве дна стека можно выбрать либо 1 либо последний элемент массива. Операционная составляющая, очевидно, это набор подпрограмм, реализующих операции: инициализировать стек, добавить в стек, извлечь из стека, стек не пуст. Операция инициализации подготавливает информационную структуру к использованию, т.е. как бы создается пустой стек. Операция «стек не пуст» булевская и возвращает истину, если в стеке есть хотя бы один элемент, и ложь в противном случае. Необходимые описания имеют вид:

const

max=100;

type

Ind=1..max; Pnt=0..max;Node=record…end; stek=record; top:Pnt; s:array[Ind] of Node; end;

procedure InitStek(var st:stek);

begin with st do top:=0; end;

procedure InStek(var st:stek; x:Node);

beginwith st do if top=max then writeln(‘Операция В СТЕК: переполнение’)

else begin top:=top+1; s[top]:=x; end; end;

procedure OutStek(var st:stek; var x:Node);

begin with st do if top=0 then writeln(‘Операция ИЗ СТЕКА: стек пуст’)

else begin x:=st[top]; top:=top-1; end; end;

function NeStek(st:stek):Boolean;

begin NeStek:=top<>0; end;

Моделирование очереди состоит в использовании массива и 2-х вспомогательных переменных, указывающих соответственно на начало (n) и конец (k) очереди. Признаком пустоты очереди является выполнение условия k<n. Поскольку в процессе выполнения программы переменная n может принимать значения от 1 до max+1, то будем считать, что в нашем распоряжении есть тип ind1=1..max+1;

Опишем также тип очереди:

type

QU=record

N:ind1;k:pnt;Q:array[ind] of node end;

Определим операции над очередью: инициализировать очередь, поместить в очередь, извлечь из очереди и проверка на пустоту.

procedure InitQU(var r:QU);

begin with r do

begin n:=1; k:=0; end; end;

procedure InQU(var r:QU;x:node);

var I:ind;

begin with r do begin if k=max then if n=1 then begin

writeln(‘операция В ОЧЕРЕДЬ: очередь переполнена’); exit; end

else begin for I:=1 to max-n+1 do Q[i]:=Q[n+i-1]; k:=max-n+1; n:=1; end;

k:=k+1; Q[k]:=x; end; end;

procedure OutQU(var r:QU; var x:node);

begin with r do if k<n then writeln(‘Операция ИЗ ОЧЕРЕДИ: очередь пуста’)

else begin x:=Q[n}; n:=n+1; end; end;

function NeQU(r:QU):boolean;

begin NeQU:=k> =n; end;

Замечание. В некоторых случаях при выполнении операции InQU приходится все элементы очереди перемещать в начало массива QU. Поскольку можно считать, что количество элементов очереди в среднем = мах/2, то такая ситуация называется массовой операцией. Очевидно, что если тип node сложен, то массовая операция для своего выполнения требует значительного времени.

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

Пример такого приема при организации очереди – это кольцевой буфер. Идея состоит в том, что массив для хранения узлов очереди считается свернутым в кольцо так, что вслед за элементом с номером мах располагается элемент с номером 1. Для моделирования очереди используется еще одно поле kol, в котором отслеживается количество узлов, хранящихся в очереди. Это поле типа Pnt.

type QUKB=record

kol:Pnt; n,k:ind; Q:array[ind] of node end;

procedure InitQUKB(var r:QUKB);

begin with r do begin kol:=0; k:=max; n:=1; end; end;

function sled(l:ind; m:word):ind;

begin if l<m then sled:=l+1 else sled:=1; end;

procedure InQUKB(var R:QUKB; x:node);

begin with R do if kol=max then writeln(‘Очередь переполнена’)

else begin k:=sled(k,max); kol:=kol+1; Q[k]:=x end; end;

procedure OutQUKB(var R:QUKB; var x:node);

begin with R do if kol<>0 then begin x:=Q[n]; n:=sled(n,max); kol:=kol-1 end; else writeln(‘Очередь пуста’); end;