Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP_Ekzamen.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
2.04 Mб
Скачать
  1. Список (list). Характеристика та приклад списку.

  1. Стек. Характеристика та приклад стеку.

Стек в інформатиці та програмуванні — різновид лінійного списку, структура даних, яка працює за принципом (дисципліною) «останнім прийшов — першим пішов» (LIFO,англ. last in, first out). Всі операції (наприклад, видалення елементу) в стеку можна проводити тільки з одним елементом, який знаходиться на верхівці стеку та був введений в стек останнім.

Стек можна розглядати як певну аналогію до стопки тарілок, з якої можна взяти верхню, і на яку можна покласти верхню тарілку (інша назва стеку — «магазин», за аналогією з принципом роботи магазину в автоматичній зброї)

Операції зі стеком

Виконання операції push

  • push ("заштовхнути елемент"): елемент додається в стек та розміщується в його верхівці. Розмір стеку збільшується на одиницю. При перевищенні розміру стека граничної величини, відбувається переповнення стека (англ. stack overflow)

  • pop ("виштовхнути елемент"): отримує елемент з верхівки стеку. При цьому він видаляється зі стеку і його місце в верхівці стеку займає наступний за ним відповідно до правила LIFO, а розмір стеку зменшується на одиницю. При намаганні "виштовхнути" елемент з вже пустого стеку, відбувається ситуація "незаповнення" стеку (англ. stack underflow)

Кожна з цих операцій зі стеком виконується за фіксований час O(1) і не залежить від розміру стеку.

Додаткові операції (присутні не у всіх реалізаціях стеку):

  • isEmpty: перевірка наявності елементів в стеку; результат: істина (true), коли стек порожній.

  • isFull: перевірка заповненості стека. Результат: істина, коли додавання нового елементу неможливе.

  • clear: звільнити стек (видалити усі елементи).

  • top: отримати верхній елемент (без виштовхування).

  • size: отримати розмір (кількість елементів) стека.

  • swap: поміняти два верхніх елементи місцями.

  • #include <iostream.h>

  • #include <stdio.h>

  • Class Stack

  • {

  • Stack ();

  • Stack (Int2 Number);

  • {

  • Push(Number);

  • };

  • ~Stack ();

  • Private:

  • Class IntUnit

  • {

  • Int2 Number;

  • IntUnit * Pointer;

  • };

  • IntUnit * Pointer;

  • Public:

  • Int2 Pop ()

  • {

  • If (Pointer==0) Return 0;

  • Int2 Number=Pointer.Number;

  • IntUnit * Pointer2=Pointer.Pointer;

  • Delete Pointer;

  • Pointer=Pointer2.Pointer;

  • //Delete Pointer2;

  • Return Number;

  • };

  • Void Push (Int2 Number)

  • {

  • IntUnit NewUnit=New NewUnit;

  • *NewUnit.Number=Number;

  • If (Pointer!=0)

  • NewUnit.Pointer=Pointer;

  • Pointer=NewUnit;

  • };

  • }

  • Void Main ()

  • {

  • }

  1. Черга (queue). Характеристика та приклад черги.

О́чередь — структура данных с дисциплиной доступа к элементам «первый пришёл — первый вышел» (FIFO, First In — First Out). Добавление элемента (принято обозначать словом enqueue — поставить в очередь) возможно лишь в конец очереди, выборка — только из начала очереди (что принято называть словом dequeue — убрать из очереди), при этом выбранный элемент из очереди удаляется.

Применение очередей

Очередь в программировании используется, как и в реальной жизни, когда нужно совершить какие-то действия в порядке их поступления, выполнив их последовательно. Примером может служить организация событий в Windows. Когда пользователь оказывает какое-то действие на приложение, то в приложении не вызывается соответствующая процедура (ведь в этот момент приложение может совершать другие действия), а ему присылается сообщение, содержащее информацию о совершенном действии, это сообщение ставится в очередь, и только когда будут обработаны сообщения, пришедшие ранее, приложение выполнит необходимое действие.

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

/*

** Класс "Очередь"

** Слава Антонов (с) 2004

** http://slava.users.otts.ru

*/

#ifndef QUEUE_H

#define QUEUE_H

#include <iostream.h>

#include <malloc.h>

// Тип элемента очереди

typedef int datatype;

// Элемент односвязного списка

struct listitem

{

datatype data;

listitem* next;

};

class equeue

{

private:

char* msg; // сообщение об ошибке

public:

equeue(const char* errmsg) { msg = strdup(errmsg); }

~equeue() { free(msg); }

const char* getmsg() { return msg; }

};

#define EQUEUE_EMPTY "Queue is empty"

class cqueue

{

private:

listitem* head; // голова односвязного списка

listitem* tail; // хвост односвязного списка

unsigned cnt; // длина очереди (кол-во элементов в ней)

public:

cqueue();

// конструктор по-умолчанию

cqueue(const cqueue&);

// конструктор копирования

// этот конструктор вызывается в следующей ситуации:

// cqueue Q2 = Q1

~cqueue() { clear(); }

// деструктор

cqueue& clear();

// удалить все элементы очереди

unsigned getCnt() const { return cnt; }

cqueue& del();

// удалить один элемент из начала очереди

bool empty() const { return head == NULL; }

// признак пустой очереди

cqueue& push(const datatype&);

// добавить элемент в конец очереди

datatype pop();

// извлеч элемент из начала очереди

const datatype& get() const;

// посмотреть элемент в начале очереди

cqueue& set(const datatype&);

// заменить элемент в начале очереди

bool operator == (const cqueue&) const;

// оператор сравнения

bool operator != (const cqueue& q) const

{ return !(*this == q); }

cqueue& operator = (const cqueue&);

// оператор присваивания

friend ostream& operator << (ostream&, const cqueue&);

// оператор вывода

};

cqueue::cqueue()

{

head = tail = NULL;

}

cqueue::cqueue(const cqueue& q)

{

head = tail = NULL;

*this = q;

}

cqueue& cqueue::clear()

{

while(!empty()) del();

return *this;

}

cqueue& cqueue::del()

{

// если стек пуст - генерируем исключение

if(empty()) throw(equeue(EQUEUE_EMPTY));

listitem* tmp = head->next; // запоминаем указатель на

// следующий элемент очереди

delete head; // удаляем элемент...

// ...и переводим указатель на следующий элемент

if(!tmp)

head = tail = NULL;

else

head = tmp;

cnt--;

return *this;

}

cqueue& cqueue::push(const datatype& data)

{

listitem* item = new listitem;

item->data = data;

item->next = NULL;

if(!head)

{

head = item;

tail = head;

} else

{

tail->next = item;

tail = item;

}

cnt++;

return *this;

}

datatype cqueue::pop()

{

if(empty()) throw(equeue(EQUEUE_EMPTY));

datatype data = head->data;

del();

return data;

}

const datatype& cqueue::get() const

{

if(empty()) throw(equeue(EQUEUE_EMPTY));

return head->data;

}

cqueue& cqueue::set(const datatype& data)

{

if(empty()) throw(equeue(EQUEUE_EMPTY));

head->data = data;

return *this;

}

bool cqueue::operator == (const cqueue& q) const

{

if(this == &q) return true;

if(getCnt() != q.getCnt()) return false;

listitem* h1 = head;

listitem* h2 = q.head;

while(h1)

{

if(h1->data != h2->data) return false;

h1 = h1->next;

h2 = h2->next;

}

return false;

}

cqueue& cqueue::operator = (const cqueue& q)

{

if(*this == q) return *this;

clear();

listitem* item = q.head;

while(item)

{

push(item->data);

item = item->next;

}

return *this;

}

ostream& operator << (ostream& s, const cqueue& q)

{

listitem* item = q.head;

while(item)

{

s << item->data << endl;

item = item->next;

}

return s;

}

#endif

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