#include<iostream>
using namespace std;
template<class T>
class List {
class Node {
public:
T element;
Node * next;
Node * previous;
Node() : next(0), previous(0) {};
Node(const T & e, Node * n = 0, Node * p = 0):
element(e), next(n), previous(p){};
~Node(){}
};
Node * head;
Node * tail;
public:
class Iterator {
Node * ihead;
Node * itail;
Node * current;
public:
Iterator() : ihead(0), current(0), itail(0) {};
Iterator(Node * h, Node * t, Node * c) : ihead(h), current(c), itail(t) {};
~Iterator(){};
Iterator & operator++() {
if (current != 0)
current = current->next;
return *this;};
Iterator & operator++(int) {
return operator++();};
T & operator*() {
return current->element;}
bool operator!=(const Iterator & i) const{
return current != i.current;}
bool operator==(const Iterator & i) const{
return current == i.current;}
bool isNull() const{
return current == 0;} Node * getCurrent() const {
return current;}
int operator-(const Iterator & i) const{
int j = 0;
Node * c = i.current;
while (c != current && c != 0){
c = c->next;
j++;
}
return j;
}
Iterator operator+(const int n){
Node * c = current;
for (int i=0; i<n && c != 0; i++)
c = c->next;
return Iterator(ihead, itail, c);
}
Iterator & operator--() {
if (current != 0)
current = current->previous;
else current = itail;
return *this;};
Iterator & operator--(int) {
return operator--();};
};
List() {
head = new Node;
tail = 0;};
~List() {
MakeEmpty(); delete head;}
bool IsEmpty(){return header->next == 0 };
void MakeEmpty(){
Node * nextNode;
for (Node * c = head->next; c != 0; c = nextNode){
nextNode = c->next;
delete c;
}
};
friend ostream & operator<<(ostream & os, const List<T> & l){
Node * nextNode;
for (Node * c = l.head->next; c != 0; c = nextNode){
os << c->element << " ";
nextNode = c->next;
}
return os;
}
Iterator begin() const{
return Iterator(head, tail, head->next);
};
Iterator end() const{
return Iterator(head, tail, 0);
};
void push_front(T x){
Node * n= new Node(x,head->next, head);
if (head->next != 0)
head->next->previous = n;
else tail = n;
head->next = n;
}
void push_back(T x){
Node * n;
if (tail == 0){ n = new Node(x, 0, head);
tail = n;
head->next = n;
}
else {
n = new Node(x, 0, tail);
tail->next = n;
tail = n;
}
};
Iterator insert(const Iterator & i, const T & x){
if (i.isNull()){
push_back(x);
return Iterator(head, tail, tail);
}
Node * currentp = i.getCurrent();
Node * n = new Node(x, currentp, currentp->previous);
currentp->previous->next = n;
currentp->previous = n;
return Iterator(head, tail, n);
}
Iterator erase(const Iterator & i){
if (i.isNull())
return Iterator(head, tail, 0);
Node * currentp = i.getCurrent();
currentp->previous->next = currentp->next;
if (currentp->next != 0)
currentp->next->previous = currentp->previous;
Node * newcur = currentp->next;
delete currentp;
return Iterator(head, tail, newcur);
}
void merge(const List<T> & l){
Iterator i = begin();
Iterator j = l.begin();
for(;i != end() && j != l.end();){
if (*i < *j)
++i;
else {
insert(i, *j);
j++;
}
}
for(;j!= l.end(); ++j)
push_back(*j);
}
void sort(){
if (head->next == 0) return; if (head->next->next == 0) return; int distance = end() - begin();
Iterator mid = begin() + distance/2;
List<T> firstHalf;
Iterator i;
for (i = begin(); i != mid; ++i)
firstHalf.push_back(*i);
List<T> secondHalf;
for (;i!=end(); ++i)
secondHalf.push_back(*i);
firstHalf.sort();
secondHalf.sort();
firstHalf.merge(secondHalf);
MakeEmpty(); tail = 0; for (i = firstHalf.begin(); i != firstHalf.end(); ++i)
push_back(*i);
}
};