#pragma once
#include <iostream>
using namespace std;
template <class type>
struct node
{
type value;
node* next;
node(type v, node* n = 0)
{
value = v;
next = n;
}
};
template <class type>
class list
{
node <type>* tail;
public:
list()
{
tail = 0;
}
bool empty()const
{
return (tail == 0);
}
int size()const
{
if (!empty())
{
int count = 0;
node <type>* temp = tail->next;
do
{
count++;
temp = temp->next;
} while (temp != tail->next);
return count;
}
return 0;
}
void print()const
{
if (!empty())
{
node <type>* temp = tail->next;
do
{
cout << temp->value << " ";
temp = temp->next;
} while (temp != tail->next);
cout << "\n";
}
}
void push_front(type element)
{
if (empty())
tail->next = tail = new node<type>(element);
else
tail->next = new node<type>(element, tail->next);
}
void push_back(type element)
{
if (empty())
tail->next = tail = new node<type>(element);
else
tail = tail->next = new node<type>(element, tail->next);
}
void insert(type element, int position)
{
if (position < 1 || position > size() + 1)
cout << "Position is out of range when inserting an element in the list." << endl;
else if (position == 1)
push_front(element);
else if (position == size() + 1)
push_back(element);
else
{
node <type>* temp = tail->next;
for (int count = 1; count < position - 1; count++)
temp = temp->next;
temp->next = new node<type>(element, temp->next);
}
}
void pop_front()
{
if (empty())
cout << "You can't delete an element in an empty list." << endl;
else if (size() == 1)
{
delete tail;
tail = 0;
}
else
{
node <type>* temp = tail->next;
tail->next = tail->next->next;
delete temp;
}
}
void pop_back()
{
if (empty())
cout << "You can't delete an element in an empty list." << endl;
else if (size() == 1)
{
delete tail;
tail = 0;
}
else
{
node <type>* temp = tail->next;
while (temp->next != tail)
temp = temp->next;
temp->next = tail->next;
delete tail;
tail = temp;
}
}
void erase_position(int position)
{
if (empty())
cout << "You can't delete an element in an empty list." << endl;
else if (position < 1 || position > size())
cout << "The position is out of range when deleting an element in the list." << endl;
else if (position == 1)
pop_front();
else if (position == size())
pop_back();
else
{
node <type>* previous = tail->next, * current = tail->next;
for (int count = 1; count < position - 1; count++)
previous = previous->next;
current = previous->next;
previous->next = current->next;
delete current;
}
}
bool search(type element)const
{
node <type>* temp = tail->next;
do
{
if (temp->value == element)
return true;
temp = temp->next;
} while (temp != tail->next);
return false;
}
int find_position(type element)const
{
int count = 1;
node <type>* temp = tail->next;
do
{
if (temp->value == element)
return count;
count++;
temp = temp->next;
} while (temp != tail->next);
return 0;
}
node <type>* find_iterator(type element)const
{
node <type>* temp = tail->next;
do
{
if (temp->value == element)
return temp;
temp = temp->next;
} while (temp != tail->next);
return 0;
}
void erase(type element)
{
if (empty())
cout << "You can't erase an element in an empty list." << endl;
else if (search(element) == 0)
cout << "The element is not found in the list." << endl;
else
erase_position(find_position(element));
}
~list()
{
while (!empty())
pop_front();
}
void operator=(list <type>& otherList)
{
while (!empty())
pop_back();
if (!otherList.empty())
{
node <type>* temp = otherList.tail->next;
tail->next = tail = new node<type>(temp->value);
do
{
temp = temp->next;
tail = tail->next = new node<type>(temp->value, tail->next);
} while (temp->next != otherList.tail->next);
}
else
tail = 0;
}
list(list <type>& otherList)
{
if (!otherList.empty())
{
node <type>* temp = otherList.tail->next;
tail->next = tail = new node<type>(temp->value);
do
{
temp = temp->next;
tail = tail->next = new node<type>(temp->value, tail->next);
} while (temp->next != otherList.tail->next);
}
else
tail = 0;
}
};