OBOWIĄZKOWE DO PRZESŁANIA: jedno zadanie
Kolejka to ADT, który pozwala zapisywać dane i następnie pobierać je w takiej kolejności, w jakiej je zapisano (ang. first in, first out, FIFO; pierwszy wchodzi, pierwszy wychodzi). Typowe operacje dla ADT QUEUE są następujące:
// https://en.cppreference.com/w/cpp/container/queue // https://en.cppreference.com/w/cpp/container/deque #include <queue> // W STL std::queue jest zbudowana na bazie std::deque. // Przykład użycia kolejki. std::queue<int> Q; // domyślnie std::deque assert( Q.empty() ); for (auto item : {1, 2, 3, 5, 7}) Q.push(item); // wstawienie do kolejki (na koniec) assert( Q.front() == 1 ); // odczyt assert( Q.back() == 7 ); // odczyt assert( Q.size() == 5 ); Q.front() = 11; // zmiana na początku kolejki Q.back() = 77; // zmiana na końcu kolejki assert( Q.front() == 11 ); assert( Q.back() == 77 ); while(!Q.empty()) { std::cout << Q.front() << std::endl; // odczyt Q.pop(); // usuwa z kolejki (z początku) 11, 2, 3, 5, 77 }
// Interfejs kolejki. template <typename T> class MyQueue { // zależne od implementacji public: MyQueue(); // default constructor ~MyQueue(); MyQueue(const MyQueue& other); // copy constructor MyQueue(MyQueue&& other); // move constructor MyQueue& operator=(const MyQueue& other); // copy assignment operator, return *this MyQueue& operator=(MyQueue&& other); // move assignment operator, return *this bool empty() const; // checks if the container has no elements std::size_t size() const; // liczba elementów w kolejce void push(const T& item); // dodanie na koniec, push_back(item) void push(T&& item); // dodanie na koniec, push_back(std::move(item)) T& front(); // zwraca koniec, nie usuwa T& back(); // zwraca koniec, nie usuwa void pop(); // usuwa początek kolejki, pop_front() void clear(); // czyszczenie listy z elementów void display(); };
Przygotować implementację realizującą ADT QUEUE na bazie tablicy cyklicznej. Kolejne elementy będą wstawiane do tablicy cyklicznie, czyli po dojściu do końca tablicy będzie przejście do początku tablicy. Rozmiar tablicy jest o jeden większy niż maksymalna planowana liczba elementów w kolejce, po to aby rozróżnić sytuacje pustej i pełnej kolejki.
// myqueue.h template <typename T> class MyQueue { T* tab; std::size_t msize; // największa możliwa liczba elementów plus jeden std::size_t head; // pierwszy do pobrania std::size_t tail; // pierwsza wolna pozycja public: MyQueue(std::size_t s=10) : msize(s+1), head(0), tail(0) { tab = new T[s+1]; assert( tab != nullptr ); } // default constructor ~MyQueue() { delete [] tab; } MyQueue(const MyQueue& other); // copy constructor MyQueue(MyQueue&& other); // move constructor // UWAGA Po przeniesieniu other.msize = 1, other.head = other.tail = 0. MyQueue& operator=(const MyQueue& other); // copy assignment operator, return *this MyQueue& operator=(MyQueue&& other); // move assignment operator, return *this // UWAGA Po przeniesieniu other.msize = 1, other.head = other.tail = 0. bool empty() const { return head == tail; } bool full() const { return (head + msize -1) % msize == tail; } std::size_t size() const { return (tail - head + msize) % msize; } std::size_t max_size() const { return msize-1; } void push(const T& item); // dodanie na koniec void push(T&& item); // dodanie na koniec T& front() { return tab[head]; } // zwraca początek T& back() { return tab[(tail + msize -1) % msize]; } // zwraca koniec void pop(); // usuwa początek void clear(); // czyszczenie listy z elementów void display(); };
Przygotować implementację realizującą ADT QUEUE na bazie listy powiązanej pojedynczo. Wykorzystać klasę SingleList [push_back(), pop_front()] lub std::forward_list [tu jest trudniej, bo nie ma back() i push_back()].
Przygotować implementację realizującą ADT QUEUE na bazie listy powiązanej podwójnie. Wykorzystać klasę DoubleList lub std::list. Możliwe są dwa warianty realizacji push() i pop(): (a) push_back() i pop_front(), (b) push_front() i pop_back().
Przygotować implementację realizującą ADT QUEUE na bazie dwóch stosów. Wykorzystać std::stack lub MyStack z zestawu nr 7.