181 lines
3.2 KiB
C++
181 lines
3.2 KiB
C++
|
|
template <typename Element>
|
|
class LinkedList
|
|
{
|
|
private:
|
|
class LinkedNode
|
|
{
|
|
public:
|
|
LinkedNode()
|
|
{
|
|
prev = next = 0;
|
|
}
|
|
LinkedNode(Element dataElement)
|
|
{
|
|
data = dataElement;
|
|
prev = next = 0;
|
|
}
|
|
Element data;
|
|
LinkedNode *next;
|
|
LinkedNode *prev;
|
|
};
|
|
|
|
LinkedNode *firstNode;
|
|
LinkedNode *lastNode;
|
|
int count;
|
|
|
|
public:
|
|
class iterator
|
|
{
|
|
private:
|
|
LinkedNode *theNode;
|
|
public:
|
|
iterator(LinkedNode & node)
|
|
{
|
|
theNode = &node;
|
|
}
|
|
iterator(LinkedNode *node)
|
|
{
|
|
theNode = node;
|
|
}
|
|
Element & operator*()
|
|
{
|
|
return theNode->data;
|
|
}
|
|
Element & operator++()
|
|
{
|
|
theNode = theNode->next;
|
|
return theNode->data;
|
|
}
|
|
Element & operator++(int dum)
|
|
{
|
|
theNode = theNode->next;
|
|
return theNode->prev->data;
|
|
}
|
|
};
|
|
|
|
class reverse_iterator
|
|
{
|
|
private:
|
|
LinkedNode *theNode;
|
|
public:
|
|
reverse_iterator(LinkedNode & node)
|
|
{
|
|
theNode = &node;
|
|
}
|
|
reverse_iterator(LinkedNode *node)
|
|
{
|
|
theNode = node;
|
|
}
|
|
Element & operator*()
|
|
{
|
|
return theNode->data;
|
|
}
|
|
Element & operator++()
|
|
{
|
|
theNode = theNode->prev;
|
|
return theNode->data;
|
|
}
|
|
Element & operator++(int dum)
|
|
{
|
|
theNode = theNode->prev;
|
|
return theNode->next->data;
|
|
}
|
|
};
|
|
|
|
LinkedList();
|
|
int numElements() { return count; }
|
|
iterator begin() { return new iterator(firstNode); }
|
|
iterator end() { return new iterator(lastNode->next); }
|
|
reverse_iterator rbegin() { return new reverse_iterator(lastNode); }
|
|
reverse_iterator rend() { return new reverse_iterator(firstNode->prev); }
|
|
LinkedList & insert(int index, Element e);
|
|
LinkedList & push_back(Element e);
|
|
LinkedList & remove(int index);
|
|
LinkedList & pop_back();
|
|
Element & operator[](int index);
|
|
};
|
|
|
|
template <typename T>
|
|
LinkedList<T>::LinkedList()
|
|
{
|
|
firstNode = lastNode = new LinkedNode();
|
|
count = 0;
|
|
}
|
|
|
|
template <typename Element>
|
|
LinkedList<Element> & LinkedList<Element>::insert(int index, Element e)
|
|
{
|
|
if (index == count-1)
|
|
push_back(e);
|
|
else if (index >= 0 && index < count)
|
|
{
|
|
LinkedNode *nptr = firstNode;
|
|
for (int i = 0; i <= index; i++)
|
|
nptr = nptr->next;
|
|
LinkedNode *newptr = new LinkedNode(e);
|
|
newptr->next = nptr;
|
|
newptr->prev = nptr->prev;
|
|
newptr->prev->next = newptr;
|
|
nptr->prev = newptr;
|
|
count++;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template <typename Element>
|
|
LinkedList<Element> & LinkedList<Element>::push_back(Element e)
|
|
{
|
|
lastNode->next = new LinkedNode(e);
|
|
lastNode->next->prev = lastNode;
|
|
lastNode = lastNode->next;
|
|
count++;
|
|
return *this;
|
|
}
|
|
|
|
template <typename Element>
|
|
LinkedList<Element> & LinkedList<Element>::remove(int index)
|
|
{
|
|
if (index == count-1)
|
|
pop_back();
|
|
else if (index >= 0 && index < count)
|
|
{
|
|
LinkedNode *nptr = firstNode;
|
|
for (int i = 0; i <= index; i++)
|
|
nptr = nptr->next;
|
|
nptr->prev->next = nptr->next;
|
|
nptr->next->prev = nptr->prev;
|
|
delete nptr;
|
|
count--;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template <typename Element>
|
|
LinkedList<Element> & LinkedList<Element>::pop_back()
|
|
{
|
|
if (count)
|
|
{
|
|
lastNode = lastNode->prev;
|
|
delete lastNode->next;
|
|
lastNode->next = 0;
|
|
count--;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template <typename Element>
|
|
Element & LinkedList<Element>::operator[](int index)
|
|
{
|
|
if (index >= 0 && index < count)
|
|
{
|
|
LinkedNode *nptr = firstNode;
|
|
for (int i = 0; i <= index; i++)
|
|
nptr = nptr->next;
|
|
return nptr->data;
|
|
}
|
|
return firstNode->data;
|
|
}
|
|
|
|
|