211 lines
4.1 KiB
C++
211 lines
4.1 KiB
C++
|
|
// LinkedList.h
|
|
// implements a LinkedList container for HOS
|
|
// Author: Josh Holtrop
|
|
// Date: 05/22/04
|
|
// Modified: 06/09/04
|
|
|
|
#ifndef __HOS_LINKEDLIST__
|
|
#define __HOS_LINKEDLIST__ __HOS_LINKEDLIST__
|
|
|
|
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;
|
|
}
|
|
void operator++() //prefix
|
|
{
|
|
theNode = theNode->next;
|
|
}
|
|
void operator++(int dum) //postfix
|
|
{
|
|
theNode = theNode->next;
|
|
}
|
|
bool operator==(const iterator & second) const
|
|
{ return theNode == second.theNode; }
|
|
bool operator!=(const iterator & second) const
|
|
{ return theNode != second.theNode; }
|
|
};
|
|
|
|
class reverse_iterator
|
|
{
|
|
private:
|
|
LinkedNode *theNode;
|
|
public:
|
|
reverse_iterator(LinkedNode & node)
|
|
{
|
|
theNode = &node;
|
|
}
|
|
reverse_iterator(LinkedNode *node)
|
|
{
|
|
theNode = node;
|
|
}
|
|
Element & operator*()
|
|
{
|
|
return theNode->data;
|
|
}
|
|
void operator++() //prefix
|
|
{
|
|
theNode = theNode->prev;
|
|
}
|
|
void operator++(int dum) //postfix
|
|
{
|
|
theNode = theNode->prev;
|
|
}
|
|
bool operator==(const reverse_iterator & second) const
|
|
{ return theNode == second.theNode; }
|
|
bool operator!=(const reverse_iterator & second) const
|
|
{ return theNode != second.theNode; }
|
|
};
|
|
|
|
/* Basic constructor */
|
|
LinkedList();
|
|
|
|
/* How many elements in the list */
|
|
int size() { return count; }
|
|
|
|
/* Return some iterators for traversing the list */
|
|
iterator begin() { return iterator(firstNode->next); }
|
|
iterator end() { return iterator(lastNode->next); }
|
|
reverse_iterator rbegin() { return reverse_iterator(lastNode); }
|
|
reverse_iterator rend() { return reverse_iterator(firstNode); }
|
|
|
|
/* Insert an element, its position will be index */
|
|
LinkedList & insert(int index, Element e);
|
|
|
|
/* Append an element to the end of the list */
|
|
LinkedList & push_back(Element e);
|
|
|
|
/* Remove an element at position index */
|
|
LinkedList & remove(int index);
|
|
|
|
/* Pop an element from the end of the list */
|
|
LinkedList & pop_back();
|
|
|
|
/* Direct access to an element in the list */
|
|
Element & operator[](int index);
|
|
};
|
|
|
|
template <typename T>
|
|
LinkedList<T>::LinkedList()
|
|
{
|
|
firstNode = lastNode = new LinkedNode(); //head node
|
|
count = 0;
|
|
}
|
|
|
|
template <typename Element>
|
|
LinkedList<Element> & LinkedList<Element>::insert(int index, Element e)
|
|
{
|
|
if (index == count)
|
|
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;
|
|
}
|
|
|
|
|
|
#endif
|
|
|