#include<iostream>
using namespace std;
typedef int ElementType;
struct node {
ElementType element;
node* next;
node* prev;
};
typedef node* Position;
class List {
node* head;
node* tail;
int counter;
public:
List() {
MakeNull();
}
void MakeNull() {
head = new node;
head->next = nullptr;
head->prev = nullptr;
tail = head;
counter = 0;
}
Position End() {
return tail;
}
void Insert(ElementType x, Position pos) {
if (pos == nullptr) pos = tail;
node* t = new node;
t->element = x;
t->next = pos->next;
t->prev = pos;
if (pos->next != nullptr)
pos->next->prev = t;
else
tail = t;
pos->next = t;
counter++;
}
void Insertback(ElementType x) {
Insert(x, tail);
}
void Delete(Position p) {
if (p == nullptr || p == head) {
cout << "Invalid position to delete\n";
return;
}
if (p->next != nullptr)
p->next->prev = p->prev;
else
tail = p->prev;
p->prev->next = p->next;
delete p;
counter--;
}
void PrintList() {
cout << "List is: ";
Position q = head->next;
while (q != nullptr) {
cout << q->element << " ";
q = q->next;
}
cout << endl;
}
Position Locate(ElementType x) {
Position p = head->next;
while (p != nullptr) {
if (p->element == x)
return p;
p = p->next;
}
return nullptr;
}
ElementType Retrieve(Position pos) {
if (pos == nullptr || pos == head) {
cout << "ERROR in retrieve\n";
return -1;
}
return pos->element;
}
Position First() {
return head;
}
Position Next(Position pos) {
return (pos != nullptr) ? pos->next : nullptr;
}
Position Previous(Position pos) {
return (pos != nullptr && pos != head) ? pos->prev : nullptr;
}
int Size() {
return counter;
}
friend void Reverse(List& l);
friend void Purge(List& l);
};
void Purge(List& l) {
Position p = l.First()->next;
while (p != nullptr) {
Position q = p->next;
while (q != nullptr) {
Position next = q->next;
if (p->element == q->element)
l.Delete(q);
q = next;
}
p = p->next;
}
}
void Reverse(List& l) {
Position current = l.head->next;
Position prevNode = nullptr;
// Update tail to the old first element
l.tail = current;
while (current != nullptr) {
Position temp = current->next;
current->next = current->prev;
current->prev = temp;
prevNode = current;
current = temp;
}
// Update head->next to point to new front node
if (prevNode != nullptr) {
l.head->next = prevNode;
prevNode->prev = l.head;
}
// Update tail's next to nullptr
if (l.tail != nullptr) {
l.tail->next = nullptr;
}
}
int main() {
List l;
l.Insertback(10);
l.Insertback(20);
l.Insertback(30);
l.Insertback(20); // duplicate
l.Insertback(60);
l.Insertback(2);
l.PrintList();
cout << "Size: " << l.Size() << endl;
Purge(l);
cout << "After Purge:\n";
l.PrintList();
Reverse(l);
cout << "After Reverse:\n";
l.PrintList();
return 0;
}