DoubleLoopLinkedList.hpp
/**
* 双向循环链表模板类
* **/
#include <iostream>
/** 节点类模板 **/
template<class T>
class NodeDLoop
{
public:
T data;
NodeDLoop<T>* prev;
NodeDLoop<T>* next;
NodeDLoop();
NodeDLoop(T value);
};
template<class T>
NodeDLoop<T>::NodeDLoop()
{
}
template<class T>
NodeDLoop<T>::NodeDLoop(T value): data(value), prev(nullptr), next(nullptr)
{
}
/** 链表类模板 **/
template<class T>
class DLLinked
{
private:
NodeDLoop<T>* first;
unsigned int num;
public:
DLLinked();
DLLinked(const DLLinked<T>& original);
~DLLinked();
bool empty() const;
void pushBack(T value);
unsigned int length() const;
void display() const;
void destroy();
void pushFront(T value);
void popBack();
void popFront();
void insert(unsigned int pos, T value);
void erase(int pos);
void revise(unsigned int pos, T value);
NodeDLoop<T>* headNode() const;
NodeDLoop<T>* last() const;
NodeDLoop<T>* find(T value);
NodeDLoop<T>* operator[](unsigned int pos);
NodeDLoop<T>* at(unsigned int pos);
DLLinked<T> operator=(const DLLinked<T>& rightHandSide);
};
template<class T>
DLLinked<T> DLLinked<T>::operator=(const DLLinked<T>& rightHandSide)
{
if (this == &rightHandSide)
{
return *this;
}
this->destroy();
NodeDLoop<T>* ptr = rightHandSide.first;
while (ptr->next != rightHandSide.first)
{
ptr = ptr->next;
pushBack(ptr->data);
}
return *this;
}
template<class T>
DLLinked<T>::DLLinked(const DLLinked<T>& original): num(0)
{
first = new NodeDLoop<T>;
first->next = first;
first->prev = first;
NodeDLoop<T>* ptr = original.first;
while (ptr->next != original.first)
{
ptr = ptr->next;
pushBack(ptr->data);
}
}
template<class T>
NodeDLoop<T>* DLLinked<T>::at(unsigned int pos)
{
if (pos < num)
{
unsigned int index = 0;
NodeDLoop<T>* ptr = first;
while (index < pos)
{
ptr = ptr->next;
++index;
}
return ptr->next;
}
std::cerr << "index out of range!" << std::endl;
exit(1);
}
template<class T>
NodeDLoop<T>* DLLinked<T>::operator[](unsigned int pos)
{
if (pos < num)
{
unsigned int index = 0;
NodeDLoop<T>* ptr = first;
while (index < pos)
{
ptr = ptr->next;
++index;
}
return ptr->next;
}
std::cerr << "index out of range!" << std::endl;
exit(1);
}
template<class T>
NodeDLoop<T>* DLLinked<T>::find(T value)
{
if (!empty())
{
NodeDLoop<T>* ptr = first;
bool isExist = false;
while (ptr->next != first)
{
ptr = ptr->next;
if (ptr->data == value)
{
isExist = true;
break;
}
}
if (isExist)
{
return ptr;
}
else
{
return nullptr;
}
}
std::cerr << "Linked is empty!" << std::endl;
return nullptr;
}
template<class T>
void DLLinked<T>::revise(unsigned int pos, T value)
{
if (pos < num)
{
unsigned int index = 0;
NodeDLoop<T>* ptr = first;
while (index < pos)
{
ptr = ptr->next;
++index;
}
ptr->next->data = value;
}
std::cerr << "index out of range!" << std::endl;
}
template<class T>
NodeDLoop<T>* DLLinked<T>::last() const
{
return first->prev;
}
template<class T>
NodeDLoop<T>* DLLinked<T>::headNode() const
{
return first;
}
template<class T>
void DLLinked<T>::erase(int pos)
{
if (pos < num)
{
NodeDLoop<T>* ptr = first;
unsigned int index = 0;
while (index < pos)
{
ptr = ptr->next;
++index;
}
std::cout << "ptr->data: " << ptr->data << std::endl;
NodeDLoop<T>* ptrNext = ptr->next;
ptr->next = ptrNext->next;
ptrNext->next->prev = ptr;
delete ptrNext;
--num;
return;
}
std::cerr << "index out of range!" << std::endl;
}
template<class T>
void DLLinked<T>::insert(unsigned int pos, T value)
{
if (!empty())
{
if (pos < num)
{
unsigned int index = 0;
NodeDLoop<T>* ptr = first;
if (index < pos)
{
ptr = ptr->next;
++index;
}
NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
newPtr->prev = ptr;
newPtr->next = ptr->next;
ptr->next = newPtr;
++num;
return;
}
else
{
NodeDLoop<T>* ptr = first;
while (ptr->next != first)
{
ptr = ptr->next;
}
NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
ptr->next = newPtr;
newPtr->prev = ptr->next;
newPtr->next = first;
++num;
return;
}
}
NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
first->next = newPtr;
newPtr->prev = first;
first->prev = newPtr;
newPtr->next = first;
++num;
}
template<class T>
void DLLinked<T>::popFront()
{
if (!empty())
{
NodeDLoop<T>* ptr = first->next;
first->next = ptr->next;
ptr->next->prev = first;
delete ptr;
--num;
return;
}
}
template<class T>
void DLLinked<T>::pushFront(T value)
{
if (!empty())
{
NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
newPtr->next = first->next;
newPtr->prev = first;
first->next = newPtr;
++num;
return;
}
NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
first->next = newPtr;
newPtr->prev = first;
first->prev = newPtr;
newPtr->next = first;
++num;
}
template<class T>
void DLLinked<T>::popBack()
{
if (!empty())
{
NodeDLoop<T>* ptr = first;
while (ptr->next->next != first)
{
ptr = ptr->next;
}
delete ptr->next;
ptr->next = first;
first->prev = ptr;
--num;
}
}
template<class T>
void DLLinked<T>::destroy()
{
NodeDLoop<T>* ptr = first;
NodeDLoop<T>* nex = first;
while (ptr->next != first)
{
ptr = ptr->next;
delete nex;
nex = ptr;
num--;
}
first->next = first;
first->prev = first;
}
template<class T>
void DLLinked<T>::display() const
{
NodeDLoop<T>* ptr = first;
while (ptr->next != first)
{
ptr = ptr->next;
std::cout << ptr->data << " ";
}
std::cout << std::endl;
}
template<class T>
unsigned int DLLinked<T>::length() const
{
return num;
}
template<class T>
void DLLinked<T>::pushBack(T value)
{
if (!empty())
{
NodeDLoop<T>* ptr = first;
while (ptr->next != first)
{
ptr = ptr->next;
}
NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
ptr->next = newPtr;
newPtr->prev = ptr->next;
newPtr->next = first;
++num;
return;
}
NodeDLoop<T>* newPtr = new NodeDLoop<T>(value);
first->next = newPtr;
newPtr->prev = first;
newPtr->next = first;
first->prev = newPtr;
++num;
}
template<class T>
bool DLLinked<T>::empty() const
{
return (first->next == first && first->prev == first);
}
template<class T>
DLLinked<T>::DLLinked(): num(0)
{
first = new NodeDLoop<T>;
first->prev = first;
first->next = first;
}
template<class T>
DLLinked<T>::~DLLinked()
{
destroy();
}