#include <iostream>
using namespace std;
struct node {
int data;
node* next;
node* prev;
node(int d) {
data = d;
next = NULL;
prev = NULL;
}
};
typedef node* position;
class DLL
{
position Head;
position tail;
int counter;
public:
DLL()
{
Head = NULL;
tail = NULL;
counter = 0;
}
position first()
{
return Head;
}
position End()
{
return tail;
}
position Next(position p)
{
if (p == NULL || p == tail)
return NULL;
return p->next;
}
position previous(position p)
{
if (p == Head)
return NULL;
return p->prev;
}
void InsertAtBeginning(int x)
{
position newNode = new node(x);
newNode->next = Head;
if (Head != NULL)
Head->prev = newNode;
else tail = newNode;
Head = newNode;
}
void Insert(int x, position p)
{
position newNode = new node(x);
if (p == NULL)
{
Head = newNode;
tail = newNode;
}
else if (p == tail)
{
newNode->prev = tail;
tail->next = newNode;
tail = newNode;
}
else
{
newNode->next = p->next;
newNode->prev = p;
p->next->prev = newNode;
p->next = newNode;
}
counter++;
}
void Delete(position p)
{
if (counter == 0)
{
cout << "List is empty\n";
return;
}
if (p == Head && p == tail)
{
delete p;
Head = NULL;
tail = NULL;
}
else if (p == Head)
{
Head = p->next;
if (Head) Head->prev = NULL;
delete p;
}
else if (p == tail)
{
tail = p->prev;
if (tail) tail->next = NULL;
delete p;
}
else
{
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
}
counter--;
}
position Locate(int x)
{
position temp = Head;
while (temp != NULL)
{
if (temp->data == x)
return temp;
temp = temp->next;
}
return NULL;
}
int Retrieve(position p)
{
if (p == NULL)
{
cout << "Position is invalid!\n";
return -1;
}
return p->data;
}
int size()
{
return counter;
}
void display()
{
if (counter == 0)
{
cout << "List is empty\n";
return;
}
position temp = Head;
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
};
void purge(DLL& l)
{
position temp1 = l.first();
while (temp1 != NULL)
{
position temp2 = l.Next(temp1);
while (temp2 != NULL)
{
position temp = l.Next(temp2);
if (l.Retrieve(temp1) == l.Retrieve(temp2))
{
l.Delete(temp2);
}
temp2 = temp;
}
temp1 = temp1->next;
}
}
void reverse(DLL& l)
{
position i = l.first();
position j = l.End();
while( i != j && i != l.previous(j))
{
position TOD1 = l.Next(i);
position TOD2 = l.previous(j);
int temp1 = l.Retrieve(i);
int temp2 = l.Retrieve(j);
l.Insert(temp2, i);
l.Delete(i);
l.Insert(temp1, j);
l.Delete(j);
i = TOD1;
j = TOD2;
}
}
int main()
{
DLL list;
list.Insert(1, list.first());//1
list.Insert(2, list.first());//1 2
list.Insert(3, list.Locate(2));//1 2 3
list.Insert(5, list.End());//1 2 3 5
list.Insert(4, list.previous(list.End()));//1 2 3 4 5
list.display();
cout << "=================Testing purge===================\n";
DLL l;
l.Insert(10, l.End());
l.Insert(20, l.End());
l.Insert(10, l.End());
l.Insert(20, l.End());
l.Insert(30, l.End());
l.Insert(30, l.End());
l.display();//10 20 10 20 30 30
purge(l);
l.display();//10 20 30
cout << "=================Testing reverse===================\n";
reverse(list);//5 4 3 2 1
list.display();
cout << "===================insert from the start===========\n";
list.InsertAtBeginning(6);
list.InsertAtBeginning(7);
list.display();//7 6 5 4 3 2 1
}