
Структуры данных.
Для информационной поддержки алгоритма стековой сортировки необходимо построить 4 стековых класса:
базовый класс Stack, производные от класса Stack классы Lstack и Hstack, класс двойной стек Dstack, производный от Lstack и Hstack. Иерархия наследования для этих классов имеет вид ациклического графа, изображенного на следующем рисунке.
Базовый класс Stack должен включать классические стековые компоненты. Он должен иметь следующие защищенные (protected) компоненты - данные: (открытые внутри иерархии классов, но закрытые вне этой иерархии)
буфер стека stbuf (BUFSIZE) - массив символов, объемом BUFSIZE;
целочисленный указатель стека int sp;
и общедоступные (public) методы:
функция char pop( ) – извлекает (выталкивает) символ из вершины стека;
функция void push (char) –проталкивает символ в вершину стека;
функция char top ( ) - возвращает код символа в вершине стека.
Класс Stack должен иметь конструктор, который инициализирует вершину пустого стека заданным символом:
Stack:: Stack (char s) {....}
Классы Lstack и Hstack - идентичные производные копии базового класса Stack. Они могут быть декларированы следующим образом:
class Lstack : public Stack {....};
и class Hstack : public Stack {....};
Их конструкторы должны вызывать конструктор базового класса Stack, с параметром, инициализирующим вершину пустого стека символом с минимальным (low):
Lstack :: Lstack (char low) : Stack (low) { }
и максимальным (high):
Hstack :: Hstack (char high) : Stack (high) { }
кодом, соответственно.
Класс Dstack образуется путем множественного наследования компонентов 2-х идентичных классов Lstack и Hstack. Его декларация имеет следующий вид:
class Dstack : public Lstack, public Hstack { };
В результате множественного наследования класс Dstack будет включать 2 копии базового класса Stack (Lstack и Hstack), компоненты которых имеют одинаковые имена. Чтобы разрешить неоднозначность вызова, необходимо в спецификации обращения к одноименным компонентам указывать имя соответствующего базового класса, например:
Lstack :: pop( ); // вытолкнуть символ из класса Lstack или
Hstack :: pop( ); // вытолкнуть символ из стека Hstack
Кроме унаследованных компонент классов Lstack и Hstack, класс Dstack должен иметь собственный общедоступный (public) метод:
void Dstack ::swap (char S) {....} - функция
обеспечивающая обмен данными между стеками Lstack и Hstack, что необходимо для размещения очередного символа.
Конструктор класса Dstack должен иметь 2 параметра типа char, значениями которых инициализируются вершины стеков Lstack и Hstack. Чтобы обеспечить такую инициализацию, конструктор класса Dstack обращается к конструкторам классов Lstack и Hstack:
Dstack :: Dstack (char low, char high) : Lstack (low) , Hstack (high) { }
Конструкторы классов Lstack и Hstack в свою очередь вызывают конструктор их базового класса Stack.
Контрольные задания.
1.Составить программу стековой сортировки потока символов в порядке убывания их кодов.
2.Составить программу стековой сортировки на базе контейнерного класса, который включает 2 компонентных класса Lstack и Hstack.
3.Составить программу сортировки потока данных на основе дека. Дек - абстрактная структура данных, в которой разрещен стековый доступ с обоих концов последовательности данных.
Литература.
1. Дж. Уокерли. Литература и программирование микро-ЭВМ., кн.1, М., Мир, 1983
2. Собоцинский В. В. Практический курс Турбо С++, М., Свет, 1993
3. http://www.uchi-it.ru/7/9/11.html “Алгоритмы + структуры данных = программы" -Никлаус Вирт.
Стек, это структура данных по принципу "последний вошел - первый вышел". Используется в процессорах в первую очередь для организации вызовов функций, которые, как правило, вложены друг в друга. Обычно это происходит так: при входе в функцию, в стек помещаются параметры и адрес возврата - адрес следующей за вызовом команды. Сама функция внутри себя еще расширяет стек под локальные переменные. При выходе из функции стек восстанавливается к виду, какой он был до входа в функцию. Поэтому локальные переменные и параметры функций нельзя использовать за пределами функции - их уже нет в стеке. Когда мы вышли из функции, из стека также извлекается адрес возврата, ранее туда помещенный, и выполнение продолжается с него, т.е. со следующей за вызовом функции команды. Указатель на вершину стека хранится в специальном регистре, а когда нужно извлечь переменную не из вершины, то берется значение из регистра плюс нужное смещение. Функция ничего не знает о состоянии стека глубже своих переменных и параметров, и соответственно, не может обращаться к параметрам и переменным функции, ее вызвавшей.
Куча – это свободное пространство под динамическую память. Ты выделяешь из нее фрагмент нужного размера, и можешь обращаться к ней из любой части программы, имея валидный указатель. Время жизни объектов на куче такое, какое потребуется, они не "умирают" при выходе за область видимости. В большинстве языков ты сам должен очистить выделенную под объект память, в других же это сделает уборщик мусора.
И стек и куча это оперативная память (в х86) И в стеке и в куче можно обратиться к любому участку памяти. Для доступа в куче к данным, храниться базовый адрес данного куска и смещение нужного байта относительно базового адреса или относительный адрес нужного байта в сегменте данных. Для доступа в стеке к любым данным, хранится вершина стека и смещение нужного байта относительно вершины стека. И в том и в другом случае доступ осуществляется за одно время и выполняется он аппаратно процессором. Разница в скорости возникает в то время, когда нужно занять/освободить место в памяти. Стек всегда готов к размещению новых данных и всегда готов у удалению данных. А кучей по сути является свободное пространство в памяти и для того чтоб разместить в ней данные, нужно обратиться к менеджеру памяти, менеджер памяти найдет свободное место нужного размера в памяти, зарегистрирует его как занятый и вернет адрес этого блока в программу. При удалении блока данных из кучи так же нужно обратиться к менеджеру памяти, менеджер памяти пометит данный кусок памяти как свободный. Плюс разный срок хранения данных: в стеке пока выполняется данная процедура, а в куче пока выполняется данный процесс.