AlgStr / Практические занятия / Практическая работа4
.docПрактическая работа № 4
Реализация линейных структур данных
Пример1: Очередь элементов типа ℓ .
head (голова)
0 0 …. 0
tail (хвост)
Добавлено в tail, выборка с head.
Необходимо реализовать объект типа очередь.
type
TQueue=object
Предоставление очереди
procedure create; методы (поведение)
function Empty:boobcan;
procedure EnQ(U: E); //добавить в хвост
procedure DeQ(var U: E); //удаление из головы
function Head E;
function Tail E; //заглянуть в очередь
.
.
.
procedure Down //разрушить очередь
end;
Способы реализации:
1.Ограниченная очередь на базе массива;
2.Неограниченная очередь на базе списка.
Особенно поучительной является (1)
Ограниченная очередь на базе массива:
Идея: есть массив
head
поля head =<указывает индекс элемента,откуда необх.читать
представления tail=<указывает на последний записанный элемент
чтобы записать необходимо продвинуть tail на 1
tail size-1
Необходимо продумать как будет выглядеть пустая очередь:
Примем, что пустая очередь выглядит: Head=0
Tail=size-1
Рассмотрим промежуточный случай:
Пусть:
Head Пусть я 1) пишу, тогда Head останется неизменным, а
Tail необходимо продвинуть на 1.
Tail 2) Читаю: head сдвигаю на следующий, а tail не
изменится.
Представим, что я только пишу, то tail доползет до конца, а мне необходимо писать с начала и у нас змейка будет постоянно бегать
tail
head
тогда
head
tail
Пусть:
Head=tail+1 (признак переполнения)
tail
head
Или случай:
head
tail читаем,читаем,получается tail head=tail+1,получаем
признак пустоты
Что делать, если tail находится в конце. Для этого предлагают загнуть очередь в баранку с помощью операции:
Next(i)= i+1,если i<size-1
0, если i>=size-1
Возникают проблемы с неоднозначностью. Посмотрим на операции писать и читать.
Когда я пишу, то условие Next,проверяю перед операцией, а когда читаю-то после.
Для этого мы на основании очереди добавляем к описанию булевое поле Empty.
Empty:
head Запишем алгоритм чтения и записи на псевдокоде.
tail
Пишу:
Если head=Next(Tail)
то
Если Empty то
Tail=Next(Tail) и
Пишу на место Tail и сбрасываю флаг Empty // в failse
Иначе ошибка переполненной очереди
Все если
Читаю:
Если Empty то
Ошибка –Пустота очереди
Иначе
Читаю с места Head
и продвигаю Head=Next(Head)
Если head=Next(Tail) то
Empty=True
Все или
Вместо того, чтобы хранить указатель на хвост и голову, то мы можем хранить указатель на голову и количество элементов-[size].
Реализация очереди на базе списка
Возникает вопрос: Где хранить Head и Tail ?
Идея 1: Необходимо хранить указатель на голову и хвост
т.е
Например: необходимо читать
-запоминаем Head в P;
-исправляем Head Next(Head);
-выдать Dispose для этого узла.
Если необходимо писать:
-выделяю узел и запоминаю в Р;
Но здесь возникают проблемы, например: если очередь пуста.
Для решения необходимо ввести фиктивный узел, для того чтобы не допускать до пустоты.
Идея 2: Хранить указатель на хвост
Tail указывает на хвост
Таким образом в этом случае кольцевой список. Но здесь тоже возникают проблемы: переполнение и опустошение.
Типичная очередь есть последовательностью элементов ℓ1, ℓ2 …. ℓn, где ℓ1-элемент в голове, ℓn-в хвосте.А затем рисовать очередь в виде . Необходимо записать как добраться к ℓ1 и ℓn.
Начинаем запись функции абстракции и инвариант представления.
И так ко всем линейным структурам.
Рассмотрим пример 2:Последовательность на базе 2-х стеков.
Последовательность –последовательный файл в оперативной памяти
Последовательный файл
Когда читаю пустой файл или же залажу на ├ -ошибка
Существует ограниченная и неограниченная последовательность.
Эту структуру можно реализовать на базе 2-х стеков:
Реализация последовательности на базе 2-х стеков:
Прочитанная часть хранится в таком виде:
Приоритетная очередь Взять о Витова Никоя.
Эластичная лента : Пример 3
Для реализации испол.
Идея: Реализация на базе двуноправленного списка.
Здесь необходимо проверять условие.
-лента пуста если Current< EndofList
пусто и Currentn.Prev=Nill
слева пусто Currentn.Prev= Nill
справа пусто Current= EndofList
Реализация стека : У.В.Н.
Классический пример на использование стека:
Пусть имеем ((х+2)+3-3*(х+3))*х
0 1 1 2 10
// Проверить правильность расстановок скобок
Если скобки разного вида:
([х+2]+3-3*[х+3])*х
Используем стек для хранения открывшихся скобок.Если закрываем скобки, то проверяем есть на верх стека такая же открывающаяся.
Необходимость функции абстракции:
Функция абстракции: типичный стек есть последовательностью ℓ1, ℓ2 …. ℓn,где ℓ1-элемент на дне стека, ℓn-элемент в вершине. ℓ1= R^.PBody^[size-1]
ℓn= R^.PBody^[Topind]
необходимо указывать