Смекни!
smekni.com

Динамические структуры данных. Решение задач. Стек. Очередь. Дек (стр. 1 из 4)

Курсовая работа

"Динамические структуры данных. Решение задач. Стек. Очередь. Дек"

Введение

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

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

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

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

1. Стек

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

Определение для стека на языке линейного списка:

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

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

Пусть Т – некоторый тип. Рассмотрим тип «стек элементов типа Т». Его значениями являются последовательности значений типа Т. Основные операции, которые используются при применении стека

· Сделать пустым;

· Добавить элемент;

· Взять элемент;

· Стек пуст;

· Вершина стека: Т;

Процедура «сделать пустым» делает стек пустым, то есть «на дне стека ничего нет», рисунок №2. Процедура «добавить элемент» добавляет элемент Х, типа Т, в конец последовательности.

Процедура «взять элемент» применима, если последовательность S непустая, она забирает из неё последний элемент, который становится значением переменной т.). Выражение «стек пуст» истинно, если последовательность S пуста. Выражение «вершина стека» определенно, если последовательность s непустая, и равно последнему элементу последовательности s (.

Реализация стека на основе массива

Будем считать, что вершина нашего стека – это первый элемент массива, тогда вершина будет находиться всегда в первой ячейке массива, а дно будет продвигаться по массиву. Для удобства договоримся пустым членам массива – свободному стеку присваивать – 1000.

Заметно, что стек ограничен по размерам: в него можно записать ограниченное количество элементов

Раздел объявления переменных и констант на языке программирования Паскаль выглядит следующим образом:

Const n=10;

туре typeelem=Integer; {объявление типа переменного}

Stack=Array Of typeelem;

Var s: stack;

Х:typeelem;

I: Integer;

Стек можно моделировать с помощью двух переменных:

1. S – стек.

2. Х – переменная для содержимого вершины.

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

Procedurelist; {процедура распечатки содержания стека}

Var i: Integer;

Begin

Writeln;

I: =1; {указатель вершины ставится на вершину стека}

While And Do Begin

Writeln;

Inc

End;

End; {list}

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

Procedurepush;

Vari: Integer; {процедура вставки}

Begin

For i: =n Downto 2 Do s: =s;

S: =x

End; {push}

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

Функция «взять элемент» в переменную заключена в том, чтобы считать элемент в переменную и удалить его из стека. Функции мы присваиваем значение вершины стека, после чего сдвигаем весь стек на одну ячейку влево. В цикле присваиваем I – тому I+1 значение. Последнему члену массива – «дно» стека присваиваем –1000.

Functionpop: typeelem; {считывание с удалением}

Var i: Integer;

Begin

Pop: =s;

For i: =1 To n-1 Do s: =s;

S: =-1000

End; {pop}

Функция вершина стека: значению функции присваиваем значение вершины стека.

Functionstacktop: typeelem; {считывание без удаления}

Begin

Stacktop: =s

End; {stacktop}

Функция стек пуст: если значение вершины стека не равняется –1000, то функции присваиваем значение логической переменной FALSE.

Function empty: Boolean; {проверканапустоту}

Begin

If s <> -1000 empty: =false;

End; {empty}

В основной программе используются выше указанные процедуры, например:

init; {процедура инициализации}

list; {распечатка содержимого стека}

For i: =1 To 3 Do

push; {вставкавстек}

Writeln;

list; {распечатка содержимого стека}

Writeln);

х:=stacktop; {считывание без удаления}

Writeln;

Writeln;

List;

For i: =1 To 2 Do Begin

х:=pop; {считывание с удалением}

Writeln

End;

Writeln;

List;

х:=pop;

Writeln;

Writeln;

list;

Writeln);

Недостаток реализации стека на основе массива – это его ограниченность в длине, для преодоления этого недостатка используют стек на основе линейного списка.


2. Очередь

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

· На начало очереди.

· На конец очереди.

Очередь можно представить в виде звеньев, каждая из которых состоит из двух полей: первое – поле элемента, второе – поле ссылки на следующий элемент очереди.

Для очередей применимы следующие операции:

· Сделать пустой.

· Добавить в очередь.

· Взять из очереди.

· Очередь пуста.

· Очередной элемент.

Реализация очереди на основе линейного списка

Описание типа переменных для реализации очереди: пользуемся рекурсивным описанием полей:

Type typeelem=Integer; типэлементаочереди

connect=^data; рекурсивное определение указателя

data=Record

elem:typeelem; тип информационной ячейки

next:connect тип указателя

End;

В этом случае каждое звено содержится в указателе предыдущего звена.

Процедура инициализации очереди включает в себя выделение памяти для создания новой ячейки, указатели присваиваются равными новой ячейке, указатель на следующее звено равно nil:

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

S: =Sn;

While s<>nil do begin

Write;

S: =s^. Next; end;

Функция проверки на пустоту очереди выглядит следующим образом:

Empty: =Sn=SK;

Функция может принимать два значения. Если начало и конец совпадают, то функция равна правде, и наоборот: не совпадают – лжи.

Процедура вставки:

new;

P^. Next: =nil;

P^. Elem: =x;

Sk^. Next: =p;

sk:=p;

создается новое звено, указатель которого равен nil, информационной ячейке придается какое-то значение, и указатель конца передвигается к этому звену.

Очередной элемент очереди: функции присваивается значение первого элемента, указатель начала передвигается на одно звено.

Remove= Sn^. Elem;

Sn: =Sn^. Next;

Sk

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

P: =Sn;

Remove= Sn^. Elem;

Sn: =Sn^. Next;

Dispose;

Тема№3: деки.

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