Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab-3_2012.doc
Скачиваний:
1
Добавлен:
22.11.2019
Размер:
237.57 Кб
Скачать

9

Міністерство освіти І науки України

національний університет “Львівська політехніка”

Кафедра ЕОМ

Структура даних СТЕК

Методичні вказівки

До лабораторної роботи № 3 з дисципліни

" Програмування. Частина III.

Структури даних та алгоритми "

для студентів напряму

6.050102 “Комп’ютерна інженерія”

Затверджено

на засідання кафедри

Електронні обчислювальні машини”.

Протокол № __ від ________ 2012 р. р.

Львів – 2012

1. МЕТА РОБОТИ

Вивчення фундаментальної абстрактної структури даних стек. Набуття практичних навичок побудови стека, дослідження динаміки його вмісту та використання стеків для розв'язання прикладних задач.

2. Теоретичні відомості

Стек - динамічна структура даних, що представляє собою впорядкований набір елементів, у якій додавання нових елементів і видалення існуючих відбувається з одного кінця, який називається вершиною стека. Згідно визначення, елементи вилучаються зі стека в порядку, зворотному їхньому додаванню в цю структуру, тобто діє принцип LIFO (Last In, Fist Out – останнім прийшов, першим вийшов).

Найбільш наочним прикладом організації стека служить дитяча пірамідка, в якій додавання й зняття кілець здійснюється саме відповідно до визначення стека. Можна уявити також стопку тарілок. Нижня тарілка із цієї стопки буде використана останньою, а верхня тарілка, яка була покладена в стопку останньою, буде використана першою. Подібне відбувається й в стеку.

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

Історично склалося так, що дві основні операції для стека - помістити в стек і вилучити зі стека - одержали назву відповідно "заштовхнути" і "виштовхнути". Тому для реалізації стека необхідно створити дві функції: "push" (заштовхнути), що поміщає елемент у вершину стека, і "pop" (виштовхнути), що вилучає з вершини стека один елемент. Необхідно також передбачити певну область у пам'яті, де фактично буде зберігатися стек. Для цього можна використати масив або можна виділити область пам'яті, використовуючи засоби динамічного розподілу пам'яті.

Приклад 1:

Нехай задана послідовність: 7 , 5 , 9 , 2 . Непарні числа цієї послідовності додаються у стек, а кожне парне число вилучає зі стеку один елемент.

Нижче показана динаміка вмісту стека під час обробки заданої послідовності:

Порожній стек

Елементи вхідної послідовності

7

5

9

2

Data[4]

Data[3]

Data[2]

Data[1]

Used

Data[0]

Data[4]

Data[3]

Data[2]

Used

Data[1]

7

Data[0]

Data[4]

Data[3]

Used

Data[2]

5

Data[1]

7

Data[0]

Data[4]

Used

Data[3]

9

Data[2]

5

Data[1]

7

Data[0]

Data[4]

Data[3]

Used

Data[2]

5

Data[1]

7

Data[0]

Функції :

push(7);

push(5);

push(9);

top(); pop();

Оскільки стек - це важлива абстракція даних, у стандартній бібліотеці С++ передбачений клас stack, для використання якого потрібно включити заголовочний файл:

#include <stack>

Повний набір стандартних операцій роботи зі стеком показаний у таблиці:

Операція

Дія

empty()

Повертає true, якщо стек порожній, і false у противному випадку

sіze()

Повертає кількість елементів у стеку

pop()

Видаляє елемент із вершини стека, але не повертає його значення

top()

Повертає значення елемента з вершини стека, але не видаляє його

push(іtem)

Додає новий елемент у стек

У наведеній програмі показані приклади використання цих операцій:

#include <stack>

#include <iostream>

int main()

{

const int ia_size = 10;

int ia[ia_size]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

// заповнення стеку

int ix = 0;

stack< int > intStack;

for ( ; ix < ia_size; ++ix )

intStack.push( ia[ ix ] );

int error_cnt = 0;

if ( intStack.size() != ia_size ) {

cerr << "Помилка! Неправильний розмір IntStack: " // cerr - вихідний потік

<< intStack.size() // повідомлень про помилки

<< "\t очікується: " << ia_size << endl,

++error_cnt;

}

int value;

while ( intStack.empty() == false )

{

// зчитування елемента з вершини стека

value = intStack.top();

if ( value != --ix ) {

cerr << " Помилка! очікується " << ix

<< " отримано " << value << endl;

++error_cnt;

}

// вилучення елемента

intStack.pop();

}

cout << "В результаті запуску програми отримано "

<< error_cnt << " помилок" << endl;

}

До двох стеків одного типу можна застосовувати операції порівняння: рівність, нерівність, менше, більше, менше або дорівнює, більше або дорівнює, якщо вони визначені над елементами стека. Елементи порівнюються попарно. Перша пара неспівпадаючих елементів визначає результат операції порівняння в цілому.

Розглянемо реалізацію стека на базі масиву з фіксованим розміром. В наведеному далі лістінгу показано заголовочний файл для шаблонного класу stack, аналогічний класу stack зі стандартної бібліотеки шаблонів STL.

// ФАЙЛ: stack1.h

// ЗАБЕЗПЕЧУВАНИЙ ШАБЛОННИЙ КЛАС: stack<Item>

//

// ШАБЛОННИЙ ПАРАМЕТР, ОПЕРАТОРИ ПЕРЕІМЕНОВАННЯ ТИПІВ

// ТА КОНСТАНТНІ ЧЛЕНИ класу stack<Item>

// Шаблонний параметр Item уявляє собою тип елементів,

// що зберігаються у стеку. Він визначається також як

// stack<Item>::value_type

// і може бути довільним вбудованим типом в мові С++ (int, char і т.д.),

// а також класом, в якому визначений конструктор по замовчуванню,

// конструктор копіювання і оператор присвоєння. Визначення типу

// stack<Item>::size_type відноситься до довільної змінної, в якій зберігається

// кількість елементів стека. В цій реалізації константа

// stack<Item>:: CAPACITY означає максимальну кількість елементів довільного

// стека (як тільки ця кількість буде досягнута, додавання

// елементів у стек припиняється).

//

// КОНСТРУКТОР ШАБЛОННОГО КЛАСУ stack<Item>:

// stack()

// Післяумова: стек ініціалізується порожнім.

//

// МОДИФІКУЮЧІ ФУНКЦІЇ-ЧЛЕНИ шаблонного класу stack<Item>:

// void push(const Item& entry)

// Передумова: size( ) < CAPACITY.

// Післяумова: в стек занесена нова копія елемента.

//

// void pop( )

// Передумова: size( ) > 0.

// Післяумова: вилучена вершина стека.

//

// КОНСТАНТНІ ФУНКЦІЇ-ЧЛЕНИ шаблонного класу stack<Item>:

// Item top( ) const

// Передумова: size( ) > 0.

// Післяумова: повертається вершина стека, однак стек при цьому

// не змінюється. Цим цей клас дещо відрізняється від стека,

// що описаний в стандартній бібліотеці шаблонів STL ( в якому

// функція top повертає посилання на елемент, що знаходиться у

// вершині стека).

//

// size_type size( ) const

// Післяумова: повертає загальну кількість елементів у стеку.

//

// bool empty( ) const

// Післяумова: повертає значення true, якщо стек порожній,

// и значення false, якщо це не так.

//

// СЕМАНТИКА ЗНАЧЕНЬ для шаблонного класу stack<Item>.

// До об'єктів класу stack<Item> можна застосувати операцію

// присвоєння і конструктор копіювання.

#ifndef MAIN_SAVITCH_STACK1_H

#define MAIN_SAVITCH_STACK1_H

#include <cstdlib> // Надає тип size_t.

namespace main_savitch_7A

{

template <class Item>

class stack

{

public:

// ОПЕРАТОРИ ПЕРЕТВОРЕННЯ ТИПІВ ТА КОНСТАНТНІ ЧЛЕНИ

typedef std::size_t size_type;

typedef Item value_type;

static const size_type CAPACITY = 30;

// КОНСТРУКТОР

stack( ) { used = 0; }

// МОДИФІКУЮЧІ ФУНКЦІЇ-ЧЛЕНИ

void push(const Item& entry);

void pop( );

// КОНСТАНТНІ ФУНКЦІЇ-ЧЛЕНИ

bool empty( ) const { return (used == 0); }

size_type size( ) const { return used; }

Item top( ) const;

private:

Item data[CAPACITY]; // Частково заповнений масив.

size_type used;

};

}

#include "stack1.template" // Директива включення реалізації.

#endif

Файл реалізації класу stack показаний в наступному лістінгу:

// ФАЙЛ: stack1.template

// РЕАЛІЗОВАНИЙ ШАБЛОННИЙ КЛАС stack<Item>:

// Цей файл входить до складу заголовочного і окремо не компілюється.

// Інваріант класу stack:

// 1. Кількість елементів у стеку зберігається у змінній-члені used.

// 2. Елементи стека знаходяться у частково заповненому масиві data. На дні стеку // знаходиться елемент data[0], далі - data[1] і так далі аж до вершини стека, // у якій розташований елемент data[used-1].

#include <cassert> // Надає макрос assert.

namespace main_savitch_7A

{

template <class Item>

const typename stack<Item>::size_type stack<Item>::CAPACITY;

template <class Item>

void stack<Item>::push(const Item& entry)

// ВИКОРИСТОВУВАНА БІБЛІОТЕКА: cassert

{

assert(size( ) < CAPACITY);

data[used] = entry;

++used;

}

template <class Item>

void stack<Item>::pop( )

// ВИКОРИСТОВУВАНА БІБЛІОТЕКА: cassert

{

assert(!empty( ));

--used;

}

template <class Item>

Item stack<Item>::top( ) const

// ВИКОРИСТОВУВАНА БІБЛІОТЕКА: cassert

{

assert(!empty( ));

return data[used-1];

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]