#include<iostream>
using namespace std;
#include<assert.h>
typedef int DataType;
struct ListNode
{
DataType _data;
ListNode *_next;
ListNode *_prev;
ListNode(DataType x)
{
_data = x;
_next = NULL;
_prev = NULL;
}
};
class List
{
private:
ListNode *_Head;
ListNode *_tail;
public:
List()
:_Head(NULL), _tail(NULL)
{
 
}
void PushBack(DataType x)
{ 
if ( _Head == _tail)
{
if (_Head == NULL)
{
_Head = _tail = new ListNode(x);
}
else
{
ListNode *tmp = new ListNode(x);
tmp->_prev = _tail;
_tail ->_next = tmp;
_tail = tmp;
}
}
else
{
ListNode *tmp = new ListNode(x);
tmp->_prev = _tail;
_tail->_next = tmp;
_tail = tmp;
}
} 
void PushFront(DataType x)
{
if (_Head == NULL)
{
_Head = _tail = new ListNode(x);
}
else
{
ListNode *tmp = new ListNode(x);
tmp->_next = _Head;
tmp->_next->_prev = tmp;
_Head = tmp;
}
 }
void PopBank()
{
if (_tail)
{
ListNode *tmp=_tail;
_tail = _tail->_prev;
_tail->_next = NULL;
delete tmp;
}
}
void PopFront()
{
if (_Head)
{
ListNode *tmp = _Head;
_Head = _Head->_next;
_Head->_prev = NULL;
delete tmp;
}
}
void Display()
{
ListNode *tmp=_Head;
while (tmp)
{
cout << tmp->_data << endl;
tmp = tmp->_next;
}
}
void Insert(ListNode* pos, DataType x)
{
assert(_Head);
ListNode *tmp = _Head;
while (tmp)
{
if (tmp == pos)
{
ListNode *cur =new ListNode(x);
cur->_next = tmp->_next;
tmp->_next->_prev = cur;
cur->_prev = tmp;
tmp->_next = cur;
}
tmp = tmp->_next;
}
}
ListNode* Find(DataType x)
{
assert(_Head);
ListNode *tmp = _Head;
while (tmp)
{
if (tmp->_data == x)
{
return tmp;
}
else
{
tmp = tmp->_next;
}
}
return NULL;
}
void Erase(DataType x)
{
assert(_Head);
ListNode *tmp = _Head;
while (tmp)
{
if (tmp->_data == x)
{
if (tmp == _Head)
{
PopFront();
return;
}
else if (tmp == _tail)
{
PopBank();
return;
}
else
{  
tmp->_prev->_next = tmp->_next;
tmp->_next->_prev = tmp->_prev;
delete tmp;
return;
}
}
else
{
tmp = tmp->_next;
}
}
}
void Reverse()
{
ListNode *begin = _Head;
ListNode *end = _tail;
while (begin != end && begin->_prev != end)
{
swap(begin->_data, end->_data);
begin = begin->_next;
end = end->_prev;
}
}
List(const List& s)
{
ListNode *tmp = _Head;
while (tmp)
{
PushBack(tmp->_data);
}
}
void clear()
{
ListNode *tmp = _Head;
while (_Head)  
{
tmp = tmp->_next;
delete _Head;
_Head = tmp;
}
}
~List()   
{
clear();
}
};
void test1()
{
List s1;
s1.PushBack(1);
s1.PushBack(2);
s1.PushBack(3);
s1.PushBack(1);
s1.Display();
}
void test2()
{
List s1;
s1.PushFront(4);
s1.PushFront(3);
s1.PushFront(2);
s1.PushFront(1);
s1.PopBank();
s1.PopFront();
s1.Display();
}
void test3()
{
List s1;
s1.PushFront(4);
s1.PushFront(3);
s1.PushFront(2);
s1.PushFront(1);
ListNode *tmp = s1.Find(2);
s1.Insert(tmp, 6);
s1.Erase(4);
s1.Display();
}
void test4()
{
List s1;
s1.PushFront(4);
s1.PushFront(3);
s1.PushFront(2);
s1.PushFront(1);
s1.Display();
s1.Reverse();
s1.Display();
}
int main()
{
//test2();
//test3();
test4();
system("pause");
return 0;
}