Глава 02
Вверх
Очередь представляет собой линейный список, доступ к элементам
Очереди находят широкое применение в программировании. В качестве примеров
Изучение принципов работы очереди начнем с рассмотрения двух функций
void qstore (Qtype i);
Функция void qstore (Qtype i); помещает элемент в конец очереди
Следует иметь в виду, что операция извлечения удаляет элемент из очереди,
Посмотрите программу:
Программа sch02_02.cpp
//параметризированный класс очереди
#include<iostream.h>
//параметризированный класс очереди
//конструктор очереди
q=new Qtype[size];
//объект помещается в очередь функция qstore()
//извлечение объекта из очереди функция qretrieve()
main()
a.qstore(100);
a.qstore(300);
cout << a.qretrieve() << " ";
queue<double> c(5),d(5);//создаем две очереди типа double
c.qstore(8.12);
c.qstore(-2.00);
cout << c.qretrieve() << " ";
return 0;
Результат:
100 300 200 400
Анализ:
Каждая очередь содержится в динамически выделяемом массиве, указатель
Размер очереди передается как параметр конструктору класса queue.
Этот размер хранится членом length структуры queue.
Вот этот конструктор:
//конструктор очереди- класса queue
q=new Qtype[size];
Обратите внимание, что размер массива, выделяемого в главной программе
Как видим, создано пять мест а введено будет четыре числа.
Переменные rloc и sloc используются для индексации очереди, причем sloc
И последнее замечание: не смотря на то что операция qretrieve()
Вверх
Программу, приведенную выше можно усовершенствовать.
Параметризированный класс циклической очереди
//параметризированный класс циклической очереди
template <class Qtype>
class queue
//конструктор очереди
q=new Qtype[size]; //создали массив в динамической памяти
//объект помещается в очередь
//извлечение объекта из очереди
for(i=0;i<10;i++) cout << a.qretrieve() << " ";
queue
return 0;
В этой версии очередь будет переполнена только в том случае, когда
Вверх
Стек по смыслу противоположен очереди так как использует принцип LIFO.
Приведенная ниже программа реализует параметризированный класс стека.
//параметризированный класс стека
template <class Stype>
class stack
void push (Stype i); //функции
//конструктор стека
//объект помещается в стек
//извлечение объекта из стека
int i;
//используем стеки типа int И double
cout << a.pop() << " ";
//демонстрируем работу символьного стека
return 0;
Результат:
20 10 6.7 100.1
Стек содержится в динамически выделяемом массиве, указателем на который
Нижеприведенный пример иллюстрирует использование стека при реализации
//простой калькулятор, использующий параметризованный стек
#include
void calculator();
//параметризированный класс стека
template
void push (Stype i); //функции
//конструктор стека
template
//объект помещается в стек
template
//извлечение объекта из стека
template
//калькулятор с четыремя действиями арифметики
void calculator()
cout << "Prosteishiy calculator \n";
do
{
case '+' :
case '-' :
case '*' :
case '.' : // Pokazaty soderzhimoe vershiny steka
default:
Назад |
Начало урока |
Вверх |
Вперед
Очереди
которого осуществляется по принципу FIFO(first-in,first-out).
Таким образом первым из очереди удаляется элемент, помещенный туда первым.
Для очереди этот метод доступа является единственным.
В отличие от массива произвольный доступ к указанному элементу не
допускается.
можно привести моделирование, диспетчеризацию задач операционной системой,
а так же буферизацию ввода-вывода.
Qtype qretrieve();
а функция Qtype qretrieve();извлекает из очереди первый элемент
и возвращает его значение.
В таблице 2.1 приведены результаты выполнения последовательности
таких операций.(стр52)
и хранившиеся в этом элементе данные будут разрушены, если только он не
сохранен где-нибудь еще. Таким образом, если из очереди удалить все элементы,
то она окажется пустой.
#include<stdlib.h>
template <class Qtype>
class queue
{
int sloc,rloc;
int length;
public:
~queue()
{delete [] q;}
void qstore(Qtype i);
Qtype qretrieve();
template <class Qtype>
queue
{
if(!q)
{
exit(1);
length =size;
sloc=rloc=0;
template <class Qtype>
void queue
{
{
return;
sloc++;
q[sloc]=i;
template <class Qtype>
Qtype queue
{
{
return 0;
rloc++;
return q[rloc];
{
b.qstore(200);
b.qstore(400);
cout << a.qretrieve() << " ";
cout << b.qretrieve() << " ";
cout << b.qretrieve() << endl;
d.qstore(9.99);
d.qstore(0.986);
cout << c.qretrieve() << " ";
cout << d.qretrieve() << " ";
cout << d.qretrieve() << endl;
8.12 -2 9.99 0.986
на который содержит переменная q.
Qtype *q;
q=new Qtype[size];
queue(int size)
length =size;
template
{
if(!q)
{
exit(1);
length = size;
sloc=rloc=0;
для поддержки очереди, превышает размер очереди.
queue
Причина этого в том, что в простейшей реализации очереди, один элемент массива
всегда пуст. Поэтому если вы хотите построить очередь из 10 элеметов,
то массив, поддерживающий эту очередь, должен иметь фактическую длину 11
элементов.
содержит адрес, по которому будет сохранен следующий элемент, а rloc
указывает индекс, определяющий следующий элемент, который будет извлечен.
При каждом извлечении элемента из очереди rloc получает приращение.
Таким образом, значение rloc приближается к значению sloc.
Когда rloc и sloc содержат одно и то же значение, очередь пуста.
не разрушает информацию, извлекаемую из очереди, эту информацию можно
считать удаленной, так как дальнейший доступ к ней будет не возможен.
Циклическая очередь
Эта программа останавливается после того как будет достигнут предельный
размер массива, используемого для хранения очереди. Вместо этого можно
циклически возвращать индекс сохранения (sloc) и индекс извлечения (rloc)
к началу массива. При такой реализации программы в очередь можно будет
поместить любое количество элементов (при том условии что элементы
не только помещаются в очередь, но и извлекаются из нее). Такая реализация
очереди называется циклической очередью, поскольку она использует
массив, в котором хранятся элементы очереди, как циклический, а не
линейный список.
Для создания циклической очереди, необходимо изменить функции qstore()
и qretrieve(),как показано ниже.
#include<iostream.h>
#include<stdlib.h>
{
int sloc,rloc; //переменные
int length;
public:
~queue()
{delete [] q;} //деструктор встроенный
void qstore (Qtype i); //функции
Qtype qretrieve();
template <class Qtype>
queue <Qtype>::queue(int size)
{
if(!q)
{
exit(1);
length = size; //длина массива на единицу больше чем длина очереди;сохранить в length
sloc=rloc=0;
template <class Qtype>
void queue <Qtype>::qstore (Qtype i)
{
{
return;
q[sloc]=i;
sloc++;
if(sloc==length) sloc = 0; //циклический переход
template <class Qtype>
Qtype queue
{
if(rloc==sloc)
{
return 0;
rloc++;
return q[rloc-1];
main()
{
int i;
//демонстрируем работу целочисленной циклической очереди
for(i=0;i<10;i++) a.qstore(i);
cout << a.qretrieve() << endl;
a.qstore(10);
cout << a.qretrieve() << endl;
a.qstore(11);
cout << a.qretrieve() << endl;
a.qstore(12);
cout << endl;
//демонстрируем работу циклической очереди
for(i=0;i<10;i++) b.qstore((double)i*1.1);
cout << b.qretrieve() << endl;
b.qstore(10.0);
cout << b.qretrieve() << endl;
b.qstore(11.1);
cout << b.qretrieve() << endl;
b.qstore(12.2);
for(i=0;i<10;i++) cout << b.qretrieve() << " ";
Вывод программы:
0
1
2
3 4 5 6 7 8 9 10 11 12
0
1.1
2.2
3.3 4.4 5.5 6.6 7.7 8.8 9.9 10 11.1 12.2
индекс извлечения, будет на 1 больше чем индекс сохранения. Очередь будет
пуста, когда rloc=sloc .Во всех остальных случаях в очереди будет
оставаться место для ввода еще одного элемента.
Стеки
(last-in,first-out).
Фактически компиляторы С++ используют стек для передачи аргументов
функциям.
Две базовых операции со стеком - сохранение и извлечение по традиции
называют push и pop соответственно. Поэтому чтобы реализовать стек
нужны две функции: push()- которая помещает элемент в стек, и pop() -
которая извлекает элемент из стека. Кроме того для реализации стека
потребуется область памяти, которая будет использоваться в качестве стека.
Для этой цели можно использовать массив, а можно выделить область памяти
с помощью new. Функция извлечения, как и в случае с очередью, удаляет
элемент из списка и уничтожает его содержимое (если только этот
элемент не хранится где-нибудь еще).
Пример работы стека приведен в таблице 2.2 стр 58.
#include<iostream.h>
#include<stdlib.h>
{
int tos; //переменные
int length;
public:
stack(int size); //конструктор
~stack()
{delete [] stck;} //деструктор встроенный
Stype pop();
template <class Stype>
stack <Stype>::stack(int size)
{
stck=new Stype[size]; //создали массив в динамической памяти
if(!stck)
{
exit(1);
length =size; //длина массива на единицу больше чем длина очереди;сохранить в length
tos=0;
template <class Stype>
void stack <Stype>::push (Stype i)
{
{
return;
stck[tos]=i;
tos++;
template <class Stype>
Stype stack <Stype>::pop()
{
{
return 0;
tos--;
return stck[tos];
main()
{
stack<double> b(10);//создаем стек из чисел типа double
stack<char> c(10);//создаем стек из переменных типа char
a.push(10);
b.push(100.1);
a.push(20);
b.push(10-3.3);
cout << a.pop() << " ";
cout << b.pop() << " ";
cout << b.pop() << endl;
for(i=0;i<10;i++) c.push((char)'A'+i);
for(i=0;i<10;i++) cout << c.pop();
cout<
JIHGFEDCBA
является переменная stck. Размер стека передается конструктору класса
стека как параметр. Этот размер содержит переменная-член length.
Переменная-член tos обозначает индекс следующей открытой позиции
стека, которая является его вершиной. Если стек пуст, переменная tos
равна нулю. Если tos больше индекса последнего сохранения, это указывает
на то, что стек заполнен.
постфиксного калькулятора.
#include
{
int tos; //переменные
int length;
public:
stack(int size); //конструктор
~stack()
{
Stype pop();
{
if(!stck)
{
exit(1);
length =size; //длина массива на единицу больше чем длина очереди;сохранить в length
tos=0;
{
{
return;
stck[tos]=i;
tos++;
{
{
return 0;
tos--;
return stck[tos];
main()
{
return 0;
{
double a, b;
char str[80];
cout << " Dlia vyhoda nazhmite 'q' \n";
cin >> str;
switch(*str)
{
b = calc.pop();
cout << a+b << endl;
calc.push(a+b);
break;
a = calc.pop();
b = calc.pop();
cout << b-a << endl;
calc.push(b-a);
break;
b = calc.pop();
cout << a*b << endl;
calc.push(a*b);
break;
b = calc.pop();
if(!a)
{
break;
cout << b/a << endl;
calc.push(b/a);
break;
calc.push(a);
cout << "Tekushee znachenie v vershine steka : " ;
cout << a << endl;
break;
Содержание