mirror of
https://github.com/kuhyx/WUT_Computer_Science.git
synced 2026-07-04 21:03:07 +02:00
407 lines
8.6 KiB
C++
407 lines
8.6 KiB
C++
|
|
#include <iostream>
|
||
|
|
|
||
|
|
using namespace std;
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
class Ring
|
||
|
|
{
|
||
|
|
private:
|
||
|
|
struct Node
|
||
|
|
{
|
||
|
|
Key key;
|
||
|
|
Info info;
|
||
|
|
Node *prev;
|
||
|
|
Node *next;
|
||
|
|
};
|
||
|
|
Node *head;
|
||
|
|
|
||
|
|
public:
|
||
|
|
class Iterator
|
||
|
|
{
|
||
|
|
private:
|
||
|
|
Node *ptr;
|
||
|
|
Node *headPtr;
|
||
|
|
Iterator(Node*);
|
||
|
|
friend class Ring<Key, Info>;
|
||
|
|
public:
|
||
|
|
Iterator();
|
||
|
|
Iterator(Ring);
|
||
|
|
Info getInfo();
|
||
|
|
Key getKey();
|
||
|
|
void printData(int);
|
||
|
|
Info operator*();
|
||
|
|
Iterator& operator++();//prefix
|
||
|
|
Iterator operator++(int);//postfix
|
||
|
|
Iterator& operator--();//prefix
|
||
|
|
Iterator operator--(int);//postfix
|
||
|
|
bool operator==(const Iterator&);
|
||
|
|
bool operator!=(const Iterator&);
|
||
|
|
bool isFirst();
|
||
|
|
bool isLast();
|
||
|
|
};
|
||
|
|
|
||
|
|
Ring();
|
||
|
|
~Ring();
|
||
|
|
void insertAtBeginning(const Key& k, const Info& inf);
|
||
|
|
void insertAtEnd(const Key& k, const Info& inf);
|
||
|
|
void removeAtBeginning();
|
||
|
|
void removeAtEnd();
|
||
|
|
void clear();
|
||
|
|
|
||
|
|
void printContent();
|
||
|
|
void printContentReverse();
|
||
|
|
|
||
|
|
Iterator begin();
|
||
|
|
Iterator end();
|
||
|
|
};
|
||
|
|
|
||
|
|
//main function
|
||
|
|
int main()
|
||
|
|
{
|
||
|
|
//test 1 - printing
|
||
|
|
|
||
|
|
Ring<char, string> ring;
|
||
|
|
|
||
|
|
ring.insertAtEnd('a', "letter 1");
|
||
|
|
ring.insertAtEnd('b', "letter 2");
|
||
|
|
ring.insertAtEnd('c', "letter 3");
|
||
|
|
ring.insertAtEnd('d', "letter 4");
|
||
|
|
ring.insertAtEnd('e', "letter 5");
|
||
|
|
|
||
|
|
cout << "Normal print:" << endl;
|
||
|
|
ring.printContent();
|
||
|
|
|
||
|
|
Ring<char, string>::Iterator *ringIt = new Ring<char, string>::Iterator(ring);
|
||
|
|
|
||
|
|
cout << endl << "Iterator print:" << endl;
|
||
|
|
int number = 0;
|
||
|
|
while (ringIt->isLast() == false)
|
||
|
|
{
|
||
|
|
ringIt->printData(number);
|
||
|
|
|
||
|
|
number++;
|
||
|
|
++ringIt;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
//------------------------------Ring functions
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
Ring<Key, Info>::Ring()
|
||
|
|
{
|
||
|
|
head = nullptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
Ring<Key, Info>::~Ring()
|
||
|
|
{
|
||
|
|
clear();
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
void Ring<Key, Info>::insertAtBeginning(const Key& k, const Info& inf)
|
||
|
|
{
|
||
|
|
if (head == nullptr)
|
||
|
|
{
|
||
|
|
Node *newNode = new Node();
|
||
|
|
newNode->key = k;
|
||
|
|
newNode->info = inf;
|
||
|
|
newNode->next = newNode;
|
||
|
|
newNode->prev = newNode;
|
||
|
|
|
||
|
|
head = newNode;
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
Node *last = head->prev;
|
||
|
|
|
||
|
|
Node *newNode = new Node();
|
||
|
|
newNode->key = k;
|
||
|
|
newNode->info = inf;
|
||
|
|
newNode->prev = last;
|
||
|
|
last->next = newNode;
|
||
|
|
|
||
|
|
newNode->next = head;
|
||
|
|
head->prev = newNode;
|
||
|
|
|
||
|
|
head = newNode;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
void Ring<Key, Info>::insertAtEnd(const Key& k, const Info& inf)
|
||
|
|
{
|
||
|
|
if (head == nullptr)
|
||
|
|
{
|
||
|
|
Node *newNode = new Node();
|
||
|
|
newNode->key = k;
|
||
|
|
newNode->info = inf;
|
||
|
|
newNode->next = newNode;
|
||
|
|
newNode->prev = newNode;
|
||
|
|
|
||
|
|
head = newNode;
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
Node *last = head->prev;
|
||
|
|
|
||
|
|
Node *newNode = new Node();
|
||
|
|
newNode->key = k;
|
||
|
|
newNode->info = inf;
|
||
|
|
|
||
|
|
newNode->prev = last;
|
||
|
|
last->next = newNode;
|
||
|
|
|
||
|
|
newNode->next = head;
|
||
|
|
head->prev = newNode;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
void Ring<Key, Info>::removeAtBeginning()
|
||
|
|
{
|
||
|
|
if (head == nullptr)
|
||
|
|
return;
|
||
|
|
|
||
|
|
if (head->next == head)
|
||
|
|
{
|
||
|
|
delete head;
|
||
|
|
head = nullptr;
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
Node *prev = head->prev;
|
||
|
|
Node *next = head->next;
|
||
|
|
|
||
|
|
prev->next = next;
|
||
|
|
next->prev = prev;
|
||
|
|
|
||
|
|
delete head;
|
||
|
|
head = next;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
void Ring<Key, Info>::removeAtEnd()
|
||
|
|
{
|
||
|
|
if (head == nullptr)
|
||
|
|
return;
|
||
|
|
|
||
|
|
if (head->next == head)
|
||
|
|
{
|
||
|
|
delete head;
|
||
|
|
head = nullptr;
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
Node *prev = head->prev->prev;
|
||
|
|
//Node *next = head;
|
||
|
|
|
||
|
|
delete head->prev;
|
||
|
|
|
||
|
|
prev->next = head;
|
||
|
|
head->prev = prev;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
void Ring<Key, Info>::clear()
|
||
|
|
{
|
||
|
|
while (head != nullptr)
|
||
|
|
removeAtEnd();
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
void Ring<Key, Info>::printContent()
|
||
|
|
{
|
||
|
|
if (head == nullptr)
|
||
|
|
return;
|
||
|
|
|
||
|
|
Node *current = head;
|
||
|
|
int number = 0;
|
||
|
|
|
||
|
|
do
|
||
|
|
{
|
||
|
|
cout << number << "# - Key: " << current->key << ", Info: " << current->info << endl;
|
||
|
|
|
||
|
|
number++;
|
||
|
|
current = current->next;
|
||
|
|
} while (current != head);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
void Ring<Key, Info>::printContentReverse()
|
||
|
|
{
|
||
|
|
if (head == nullptr)
|
||
|
|
return;
|
||
|
|
|
||
|
|
|
||
|
|
if (head->next == head)
|
||
|
|
{
|
||
|
|
cout << "0# - Key: " << head->key << ", Info: " << head->info << endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
Node *current = head->prev;
|
||
|
|
int number = 0;
|
||
|
|
|
||
|
|
do
|
||
|
|
{
|
||
|
|
cout << number << "# - Key: " << current->key << ", Info: " << current->info << endl;
|
||
|
|
|
||
|
|
number++;
|
||
|
|
current = current->prev;
|
||
|
|
} while (current != head);
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
typename Ring<Key, Info>::Iterator Ring<Key, Info>::begin()
|
||
|
|
{
|
||
|
|
Ring<Key, Info>::Iterator tempIter = new Ring<Key, Info>::Iterator(head);
|
||
|
|
|
||
|
|
return tempIter;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
typename Ring<Key, Info>::Iterator Ring<Key, Info>::end()
|
||
|
|
{
|
||
|
|
Ring<Key, Info>::Iterator tempIter = new Ring<Key, Info>::Iterator(head->prev);
|
||
|
|
|
||
|
|
return tempIter;
|
||
|
|
}
|
||
|
|
|
||
|
|
//------------------------------Ring Iterator functions
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
Ring<Key, Info>::Iterator::Iterator()
|
||
|
|
{
|
||
|
|
ptr = nullptr;
|
||
|
|
headPtr = nullptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
Ring<Key, Info>::Iterator::Iterator(Node* nodePtr)
|
||
|
|
{
|
||
|
|
ptr = nodePtr;
|
||
|
|
headPtr = nodePtr;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
Ring<Key, Info>::Iterator::Iterator(Ring<Key, Info> ring)
|
||
|
|
{
|
||
|
|
ptr = ring.head;
|
||
|
|
headPtr = ring.head;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
Info Ring<Key, Info>::Iterator::getInfo()
|
||
|
|
{
|
||
|
|
if (ptr != nullptr)
|
||
|
|
return ptr->info;
|
||
|
|
else
|
||
|
|
throw "Iterator was nullptr";
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
Key Ring<Key, Info>::Iterator::getKey()
|
||
|
|
{
|
||
|
|
if (ptr != nullptr)
|
||
|
|
return ptr->key;
|
||
|
|
else
|
||
|
|
throw "Iterator was nullptr";
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
void Ring<Key, Info>::Iterator::printData(int number)
|
||
|
|
{
|
||
|
|
if (ptr != nullptr)
|
||
|
|
cout << number << "# - Key: " << ptr->key << ", Info: " << ptr->info << endl;
|
||
|
|
else
|
||
|
|
cout << "Tried to print an empty iterator" << endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
Info Ring<Key, Info>::Iterator::operator*()
|
||
|
|
{
|
||
|
|
if (ptr != nullptr)
|
||
|
|
return ptr->info;
|
||
|
|
else
|
||
|
|
throw "Iterator was nullptr";
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
typename Ring<Key, Info>::Iterator& Ring<Key, Info>::Iterator::operator++()
|
||
|
|
{
|
||
|
|
if (ptr != nullptr && headPtr != nullptr && ptr->next != headPtr)
|
||
|
|
ptr = ptr->next;
|
||
|
|
|
||
|
|
return *this;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
typename Ring<Key, Info>::Iterator Ring<Key, Info>::Iterator::operator++(int)
|
||
|
|
{
|
||
|
|
Ring<Key, Info>::Iterator incremented = *this;
|
||
|
|
|
||
|
|
++(*this);
|
||
|
|
return incremented;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
typename Ring<Key, Info>::Iterator& Ring<Key, Info>::Iterator::operator--()
|
||
|
|
{
|
||
|
|
if (ptr != nullptr && headPtr != nullptr && ptr != headPtr)
|
||
|
|
ptr = ptr->prev;
|
||
|
|
|
||
|
|
return *this;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
typename Ring<Key, Info>::Iterator Ring<Key, Info>::Iterator::operator--(int)
|
||
|
|
{
|
||
|
|
Ring<Key, Info>::Iterator decremented = *this;
|
||
|
|
|
||
|
|
--(*this);
|
||
|
|
return decremented;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
bool Ring<Key, Info>::Iterator::operator==(const Ring<Key, Info>::Iterator& iter)
|
||
|
|
{
|
||
|
|
if (ptr == iter->ptr)
|
||
|
|
return true;
|
||
|
|
else
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
bool Ring<Key, Info>::Iterator::operator!=(const Ring<Key, Info>::Iterator& iter)
|
||
|
|
{
|
||
|
|
if (operator==(this))
|
||
|
|
return false;
|
||
|
|
else
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
bool Ring<Key, Info>::Iterator::isLast()
|
||
|
|
{
|
||
|
|
cout << (ptr != nullptr) << " " << (headPtr != nullptr) << " " << (ptr->next == headPtr) << endl;
|
||
|
|
if (ptr != nullptr && headPtr != nullptr && ptr->next == headPtr)
|
||
|
|
return true;
|
||
|
|
else
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename Key, typename Info>
|
||
|
|
bool Ring<Key, Info>::Iterator::isFirst()
|
||
|
|
{
|
||
|
|
if (ptr != nullptr && headPtr != nullptr && ptr == headPtr)
|
||
|
|
return true;
|
||
|
|
else
|
||
|
|
return false;
|
||
|
|
}
|