📄 d_list.h
字号:
#ifndef LIST_CLASS
#define LIST_CLASS
#include <iostream>
#include <string>
#include "d_dnode.h" // dnode class
#include "d_except.h" // exception classes
using namespace std;
template <typename T>
class miniList
{
public:
// include the iterator nested classes
#include "d_liter.h"
miniList();
// constructor. create an empty list
miniList(int n, const T& item = T());
// constructor. build a list with n elements, all having
// the value item
miniList(T* first, T* last);
// constructor. build a list whose data comes from the
// pointer range [first, last)
miniList(const miniList<T>& obj);
// copy constructor
~miniList();
// destructor
miniList<T>& operator= (const miniList<T>& rhs);
// overloaded assignment operator
int size() const;
// return the size of the list
bool empty() const;
// is the list empty
void push_front(const T& item);
// insert item at the front of the list
// Postcondition: the list size increases by 1
void push_back(const T& item);
// insert item at the back of the list
// Postcondition: the list size increases by 1
iterator insert(iterator pos, const T& item);
// insert item before pos.
// Postcondition: the list size increases by 1
void pop_front();
// erase the front of the list.
// Precondition: the list is not empty. if the list is
// empty, the function throws the underflowError exception.
// Postcondition: the list size decreases by 1
void pop_back();
// erase the back of the list.
// Precondition: the list is not empty. if the list is
// empty, the function throws the underflowError exception.
// Postcondition: the list size decreases by 1
void erase(iterator pos);
// erase the list element at pos
// Precondition: the list is not empty. if the list is
// empty, the function throws the underflowError exception.
// Postcondition: the list size decreases by 1
T& front();
// return a reference to the value at the front of the list.
// Precondition: the list is not empty. if the list is
// empty, the function throws the underflowError exception
const T& front() const;
// constant version of front()
T& back();
// return a reference to the value at the back of the list.
// Precondition: the list is not empty. if the list is
// empty, the function throws the underflowError exception
const T& back() const;
// constant version of back()
iterator begin();
// return an iterator pointing at the first node in the list
// or end() if the list is empty
const_iterator begin() const;
// constant version of begin()
iterator end();
// return an iterator pointing just past the last node of
// the list
const_iterator end() const;
// constant version of end()
private:
// header (sentinel) node
dnode<T> *header;
// number of elements in the list
int listSize;
dnode<T> *getDNode(const T& item);
// allocate a dnode object with the value item and
// return a pointer to it. throw the memoryAllocationError
// exception of the memory allocation fails
dnode<T> *dinsert(dnode<T> *curr, const T& item);
// insert item before node curr of the linked list and
// return the address of the new node
void derase(dnode<T> *curr);
// erase node curr from the linked list.
// Precondition: the list is not empty. the functions that
// call derase() check the precondition
};
template <typename T>
dnode<T> *miniList<T>::getDNode(const T& item)
{
// pointer to the new node
dnode<T> *newNode;
// allocate the new node and verify that the
// allocation succeeded
newNode = new dnode<T>(item);
if (newNode == NULL)
throw memoryAllocationError("miniList(): memory allocation failure");
// return the address of the new node
return newNode;
}
template <typename T>
dnode<T> *miniList<T>::dinsert(dnode<T> *curr, const T& item)
{
// allocate the new node
dnode<T> *newNode = getDNode(item);
// insert newNode before curr
newNode->prev = curr->prev;
newNode->next = curr;
curr->prev->next = newNode;
curr->prev = newNode;
return newNode;
}
template <typename T>
void miniList<T>::derase(dnode<T> *curr)
{
// unlink the node from the list
curr->prev->next = curr->next;
curr->next->prev = curr->prev;
// delete the node
delete curr;
}
// list size is 0
template <typename T>
miniList<T>::miniList(): listSize(0)
{
// create an empty list
header = new dnode<T>;
if (header == NULL)
throw memoryAllocationError("miniList(): memory allocation failure");
}
// list size is n
template <typename T>
miniList<T>::miniList(int n, const T& value): listSize(n)
{
int i;
// create an empty list
header = new dnode<T>;
if (header == NULL)
throw memoryAllocationError
("miniList(): memory allocation failure");
// insert n copies of value at the front of the list
for (i=0;i < n;i++)
dinsert(header->next, value);
}
// initialize listSize to 0
template <typename T>
miniList<T>::miniList(T* first, T* last): listSize(0)
{
T *curr = first;
// create an empty list
header = new dnode<T>;
if (header == NULL)
throw memoryAllocationError("miniList(): memory allocation failure");
// insert the values in the range [first, last) at the
// back of the list. increment listSize in each iteration
while (curr != last)
{
dinsert(header, *curr);
curr++;
listSize++;
}
}
template <typename T>
miniList<T>::miniList(const miniList<T>& obj): listSize(obj.listSize)
{
// curr moves through the nodes in obj, and end marks the finish
// of a traversal through obj
dnode<T> *curr = obj.header->next, *end = obj.header;
// create an empty list
header = new dnode<T>;
if (header == NULL)
throw memoryAllocationError
("miniList(): memory allocation failure");
// insert the values in the linked list obj.header
// at the back of the current list
while (curr != end)
{
dinsert(header, curr->nodeValue);
curr = curr->next;
}
}
template <typename T>
miniList<T>::~miniList()
{
// erase the front of the list until it is empty
while (header->next != header)
derase(header->next);
// the list has no nodes
listSize = 0;
// delete the header node
delete header;
}
template <typename T>
miniList<T>& miniList<T>::operator=(const miniList<T>& rhs)
{
// curr moves through the nodes in rhs, and end marks the finish
// of a traversal through rhs
dnode<T> *curr = rhs.header->next, *end = rhs.header;
// can't assign list to itself
if (this == &rhs)
return *this;
// erase the current list
while (header->next != header)
derase(header->next);
// insert the elements of rhs at the back of the list
while (curr != end)
{
dinsert(header, curr->nodeValue);
curr = curr->next;
}
// list size is the size of rhs
listSize = rhs.listSize;
return *this;
}
template <typename T>
int miniList<T>::size() const
{
return listSize;
}
template <typename T>
bool miniList<T>::empty() const
{
return listSize == 0;
}
template <typename T>
void miniList<T>::push_front(const T& item)
{
// insert at the front
dinsert(header->next, item);
// increment the list size
listSize++;
}
template <typename T>
void miniList<T>::push_back(const T& item)
{
// insert at the back
dinsert(header, item);
// increment the list size
listSize++;
}
template <typename T>
miniList<T>::iterator miniList<T>::insert(iterator pos, const T& item)
{
// record the current node's address in curr. newNode will be
// the address of the node we insert
dnode<T> *curr = pos.nodePtr, *newNode;
// insert item before curr and capture the new node's address
newNode = dinsert(curr, item);
// increment the list size
listSize++;
// constructor converts newNode to an iterator
return iterator(newNode);
}
template <typename T>
void miniList<T>::pop_front()
{
if (listSize == 0)
throw underflowError("miniList pop_front(): list is empty");
// erase the front
derase(header->next);
// decrement the list size
listSize--;
}
template <typename T>
void miniList<T>::pop_back()
{
if (listSize == 0)
throw underflowError("miniList pop_back(): list is empty");
// erase the back
derase(header->prev);
// decrement the list size
listSize--;
}
template <typename T>
void miniList<T>::erase(iterator pos)
{
if (listSize == 0)
throw underflowError("miniList erase(): list is empty");
// retrieve the address of the node to be erased
dnode<T> *curr = pos.nodePtr;
// erase the node from the list
derase(curr);
// decrement the list size
listSize--;
}
template <typename T>
T& miniList<T>::front()
{
if (listSize == 0)
throw underflowError("miniList front(): list is empty");
return header->next->nodeValue;
}
template <typename T>
const T& miniList<T>::front() const
{
if (listSize == 0)
throw underflowError("miniList front(): list is empty");
return header->next->nodeValue;
}
template <typename T>
T& miniList<T>::back()
{
if (listSize == 0)
throw underflowError("miniList back(): list is empty");
return header->prev->nodeValue;
}
template <typename T>
const T& miniList<T>::back() const
{
if (listSize == 0)
throw underflowError("miniList back(): list is empty");
return header->prev->nodeValue;
}
// note that in each of begin() and end(), a
// private iterator/const_iterator constructor converts
// the pointer into an iterator
template <typename T>
miniList<T>::iterator miniList<T>::begin()
{
// private iterator constructor builds an iterator object
// from the dnode pointer
return iterator(header->next);
}
template <typename T>
miniList<T>::const_iterator miniList<T>::begin() const
{
// private constructor builds a const_iterator object
// from the dnode pointer
return const_iterator(header->next);
}
template <typename T>
miniList<T>::iterator miniList<T>::end()
{
// private constructor builds an iterator object
// from the dnode pointer
return iterator(header);
}
template <typename T>
miniList<T>::const_iterator miniList<T>::end() const
{
// private constructor builds a const_iterator object
// from the dnode pointer
return const_iterator(header);
}
#endif // LIST_CLASS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -