#include <iostream>
#include <stdlib.h>
using namespace std;
template <typename Key>
class Ring
{
struct Node
{
Key key;
Node *next;
Node *prev;
};
Node *any = NULL;
public:
/******* iterator class methods definitions ********/
class iterator
{
Node *el;
public:
iterator(){
el = NULL;}
~iterator(){}
iterator(const iterator ©Iter){
el = copyIter.el;}
iterator(Node *copyEl){
el = copyEl;}
const iterator &operator = (const iterator ©Iter){
el = copyIter.el;
return *this;}
bool operator == (const iterator &comp)const{
return el == comp.el;}
bool operator != (const iterator &comp)const{
return el != comp.el;}
iterator operator + (const unsigned int number)const{
iterator new_iter = *this;
for(int i = 0; i < number; i++)
new_iter++;
return new_iter;}
iterator operator ++ (){
if(el != NULL)
return el = el->next;}
iterator operator ++ (int){
iterator copy_iter(el);
if(el != NULL)
return el = el->next;}
iterator operator - (const unsigned int number)const{
iterator new_iter = *this;
for(int i = 0; i < number; i++)
new_iter--;
return new_iter;}
iterator operator --(){
if(el != NULL)
return el = el->prev;}
iterator operator -- (int){
iterator copy_iter(el);
if(el != NULL)
return el = el->prev;}
Key getKey(){
//if(!this->isNULL())
return el->key;
//cerr << "getKey(): (iterator = NULL)" << endl;
}
bool isNULL(){
if(el)
return false;
return true;}
};
/******* methods ********/
Ring();
~Ring();
Ring(const Ring<Key> &Ring);
friend ostream &operator << (ostream &o, const Ring<Key> &Ring){Ring.print(); return o;};
bool operator ==(const Ring<Key> &Ring);
bool operator != (const Ring<Key> &Ring);
Ring<Key> &operator = (const Ring<Key> &Ring);
Ring<Key> operator + (const Ring<Key> &second)const;
Ring<Key> operator - (const Ring<Key> &second)const;
bool insertFront(const Key &key);
bool insertLast(const Key &key);
bool insertAt(int pos, const Key &key);
bool insertAfter(const Key &where, const Key &key);
bool popByKey(const Key &key);
bool popLast();
bool popFront();
bool ifExists(const Key &key);
bool isEmpty()const;
int length()const;
void print()const;
bool clear();
void reverse();
/******* additional iterators definitions *******/
iterator begin()const{
return iterator(any);}
iterator end()const{
return iterator(any->prev);}
};
/******* methods definitions ********/
template <typename Key>
Ring<Key>::Ring()
{
this->any = NULL;
cout << "Constructor: (Empty Ring created)" << endl;
}
template <typename Key>
Ring<Key>::~Ring()
{
if(any == NULL)
cout << "Destructor: ( Ring deleted )" << endl;
Node *curr = any;
if(curr)
{
while(any != NULL)
{
this->popLast();
}
cout << "Destructor: ( Ring deleted )" << endl;
}
}
template <typename Key>
Ring<Key>::Ring(const Ring<Key> &Ring)
{
this->any = NULL;
if(Ring.any)
{
Node *curr = Ring.any;
do
{
this->insertLast(curr->key);
curr = curr->next;
}
while(curr != Ring.any);
}
}
template <typename Key>
bool Ring<Key>::popLast()
{
if(any == NULL)
return true;
Node *curr = any;
if(curr->next == curr) // one Node
{
any = NULL;
delete curr;
return true;
}
if(curr->next->next == curr) // two Nodes
{
Node *temp = curr->next;
curr->next = curr;
curr->prev = curr;
delete temp;
return true;
}
do
{
if(curr->next->next == any) // Last Node
{
Node *temp = curr->next;
temp->next->prev = curr;
curr->next = temp->next;
delete temp;
return true;
}
curr = curr->next;
}
while(curr != any);
return false;
}
template <typename Key>
bool Ring<Key>::insertFront(const Key &key)
{
Node* curr = any;
if(curr == NULL)
{
Node *newNode = new Node;
newNode->key = key;
newNode->next = newNode;
newNode->prev = newNode;
any = newNode;
return true;
}
if(curr->next == curr) // one Node
{
Node *newNode = new Node;
newNode->key = key;
newNode->next = curr;
newNode->prev = curr;
curr->prev = newNode;
curr->next = newNode;
any = newNode;
return true;
}
Node *newNode = new Node; // many Nodes
newNode->key = key;
newNode->next = curr;
newNode->prev = curr->prev;
curr->prev->next = newNode;
curr->prev = newNode;
any = newNode;
return true;
}
template <typename Key>
bool Ring<Key>::operator == (const Ring<Key> &Ring)
{
if(this->isEmpty() && Ring.isEmpty())
return true;
if(this->length() != Ring.length())
return false;
Node *curr1 = this->any;
Node *curr2 = Ring.any;
do
{
if(curr1->key != curr2->key)
return false;
curr1 = curr1->next;
curr2 = curr2->next;
}
while(curr1 != this->any);
return true;
}
template <typename Key>
bool Ring<Key>::insertLast(const Key &key)
{
Node* curr = any;
if(curr == NULL) // no elements
{
this->insertFront(key);
return true;
}
if(curr->next == curr) // one Node
{
Node *newNode = new Node;
newNode->key = key;
newNode->next = curr;
newNode->prev = curr;
curr->prev = newNode;
curr->next = newNode;
return true;
}
do
{
if(curr->next == any)
{
Node *newNode = new Node;
newNode->key = key;
newNode->next = curr->next;
newNode->prev = curr;
curr->next->prev = newNode;
curr->next = newNode;
return true;
}
curr = curr->next;
}
while(curr != any);
return false;
}
template<typename Key>
bool Ring<Key>::isEmpty()const
{
if(any == NULL)
{
cout << "isEmpty(): (Ring empty)" << endl;
return true;
}
return false;
}
template <typename Key>
int Ring<Key>::length()const
{
int count = 0;
Node *curr = any;
if(curr == NULL)
return count;
do
{
count++;
curr = curr->next;
}
while(curr != any);
return count;
}
template<typename Key>
void Ring<Key>::print()const
{
Node * curr = any;
if(curr == NULL)
{
cout << "print(): (Ring empty)" << endl;
return;
}
do
{
cout << "\t(" << curr->key<< ")";
curr = curr->next;
}
while(curr != any);
cout << endl;
}
/******* external function ********/
/****** Example of the split function:
split (r3,r1,true,3,r2,false,6)
r3= 1,2,3,4,5
r1= 1,3,5
r2= 2,5,3,1,4,2
********/
template <typename Key>
Ring<Key> split(const Ring<Key> &source,Ring<Key> &result1, bool dir1, int len1, Ring<Key> &result2, bool dir2, int len2){
typename Ring<Key>::iterator i1 = source.begin();
typename Ring<Key>::iterator i2 = source.begin();
/*I moved second iterator to the 2nd position in original Ring*/
i2++;
if (source.isEmpty()){
cout<<"Empty source Ring"<<endl;}
if (source.length()==1||source.length()==2){
return source;
}
if((len1 <= 0) || (len2 <= 0))
{
cout << "split():(incorrect lengths)" << endl;
}
if(!i1.isNULL()){
for(int i = 0; i < len1; i++)
{
result1.insertLast(i1.getKey());
if(dir1){
i1++;
i1++;;
}
else
{i1--;
i1--;
}}}
cout<<result1;
if(!i2.isNULL()){
for(int i = 0; i < len2; i++)
{
result2.insertLast(i2.getKey());
if(dir2){
i2++;
i2++;
}
else
{i2--;
i2--;
}}}
cout<<result2;
}
int main()
{
Ring<int> R1,R2,R3,R4,R5;
R1.insertLast(2);
R1.insertLast(3);
R1.insertLast(4);
R1.insertLast(5);
R1.insertLast(6);
R1.insertLast(1);
R2.insertLast(10);
R2.insertLast(20);
R2.insertLast(30);
R2.insertLast(40);
R2.insertLast(50);
R2.insertLast(60);
R2.insertLast(70);
cout<<"Split function:"<<endl;
split(R1,R3,false,3,R4,false,6);
R5.insertLast(10);
R5.insertLast(20);
R5.insertLast(30);
R5.insertLast(50);
R5.insertLast(50);
R5.insertLast(60);
R5.insertLast(70);
R5.print();
return 0;
}