// nodelist.h
#ifndef NODELIST_H
#define NODELIST_H
template<typename Type> class DoublyList;
template<typename Type> class ListNode
{
private:
friend class DoublyList<Type>;
ListNode() : m_pprior(NULL),m_pnext(NULL){}
ListNode(const Type item, ListNode<Type>* prior = NULL, ListNode<Type>* next = NULL)
: m_data(item), m_pprior(prior), m_pnext(next){}
~ListNode()
{
m_pprior = NULL;
m_pnext = NULL;
}
public:
Type GetData();
private:
Type m_data;
ListNode* m_pprior;
ListNode* m_pnext;
};
template<typename Type> Type ListNode<Type>::GetData()
{
return this->m_data;
}
#endif // NODELIST_H
// doublelist.h
#ifndef DOUBLELIST_H
#define DOUBLELIST_H
#include "nodelist.h"
#include <iostream>
template<typename Type> class DoublyList
{
public:
DoublyList() : head(new ListNode<Type>())
{
head->m_pprior = head;
head->m_pnext = head;
}
~DoublyList()
{
MakeEmpty();
delete head;
}
public:
void MakeEmpty();
int Length();
ListNode<Type>* Find(int n = 0);
ListNode<Type>* FindData(Type item);
bool Insert(Type item, int n = 0);
Type Remove(int n = 0);
Type Get(int n = 0);
void Print();
private:
ListNode<Type> *head;
};
template<typename Type> void DoublyList<Type>::MakeEmpty()
{
ListNode<Type> *pIterator = head->m_pnext, *pdel;
while(pIterator != head)
{
pdel = pIterator;
pIterator = pIterator->m_pnext;
delete pdel;
}
head->m_pnext = head;
head->m_pprior = head;
}
template<typename Type> int DoublyList<Type>::Length()
{
ListNode<Type> *pprior = head->m_pprior, *pnext = head->m_pnext;
int count = 0;
while(1)
{
if(pprior->m_pnext == pnext) // pprior == head
{
break;
}
if(pprior == pnext && pprior != head)
{
count++;
break;
}
count += 2;
pprior = pprior->m_pprior;
pnext = pnext->m_pnext;
}
return count;
}
template<typename Type> ListNode<Type>* DoublyList<Type>::Find(int n)
{
if(n < 0)
{
std::cout << "The n is out of boundary" << std::endl;
return NULL;
}
ListNode<Type> *pcursor = head->m_pnext;
for( int i = 0; i < n; i++)
{
pcursor = pcursor->m_pnext;
if( pcursor == head)
{
std::cout << "The n is out of boundary" << std::endl;
return NULL;
}
}
return pcursor;
}
template<typename Type> ListNode<Type>* DoublyList<Type>::FindData(Type item)
{
ListNode<Type> *pcursorP = head->m_pprior;
ListNode<Type> *pcursorN = head->m_pnext;
while(pcursorP->m_pnext != pcursorN && pcursorP != pcursorN)
{
if(pcursorP->m_data == item)
{
return pcursorP;
}
if(pcursorN->m_data == item)
{
return pcursorN;
}
pcursorP = pcursorP->m_pprior;
pcursorN = pcursorN->m_pnext;
}
std::cout << "can't find the item you want to find" << std::endl;
return NULL;
}
template<typename Type> bool DoublyList<Type>::Insert(Type item, int n)
{
if(n<0)
{
std::cout << "The n is out of boundary" << std::endl;
return 0;
}
ListNode<Type> *newnode = new ListNode<Type>(item), *pcursor = head;
if(newnode == NULL)
{
std::cout << __FUNCTION__ << " error " << std::endl;
exit(1);
}
for(int i = 0; i < n; i++)
{
pcursor = pcursor->m_pnext;
if(pcursor == head)
{
std::cout << "The n is out of boundary" << std::endl;
exit(1);
}
}
newnode->m_pnext = pcursor->m_pnext;
newnode->m_pprior = pcursor;
newnode->m_pnext->m_pprior = newnode;
pcursor->m_pnext = newnode;
return 1;
}
template<typename Type> Type DoublyList<Type>::Remove(int n)
{
if(n<0)
{
std::cout << "The n is out of boundary" << std::endl;
exit(1);
}
ListNode<Type> *pcursor = head, *pdel = NULL;
for(int i = 0; i < n; i++)
{
pcursor = pcursor->m_pnext;
if(pcursor == head)
{
std::cout << "The n is out of boundary" << std::endl;
exit(1);
}
}
pdel = pcursor;
pcursor->m_pprior->m_pnext = pdel->m_pnext;
pcursor->m_pnext->m_pprior = pdel->m_pprior;
Type tmp = pdel->m_data;
delete pdel;
return tmp;
}
template<typename Type> Type DoublyList<Type>::Get(int n)
{
if(n<0)
{
std::cout << "The n is out of boundary" << std::endl;
exit(1);
}
ListNode<Type> *pcursor = head;
for(int i = 0; i < n; i++)
{
pcursor = pcursor->m_pnext;
if(pcursor == head)
{
std::cout << "The n is out of boundary" << std::endl;
exit(1);
}
}
return pcursor->m_data;
}
template<typename Type> void DoublyList<Type>::Print()
{
ListNode<Type> *pcursor = head;
std::cout << "head";
while(pcursor->m_pnext != head)
{
std::cout << "--->" << pcursor->m_pnext->m_data;
pcursor = pcursor->m_pnext;
}
std::cout << "--->over" << std::endl << std::endl << std::endl;
}
#endif // DOUBLELIST_H
// main.cpp
#include <iostream>
#include "doublelist.h"
using namespace std;
int main(int argc, char *argv[])
{
DoublyList<int> list;
for(int i = 0; i < 20; i++)
{
list.Insert(i*3, i);
}
cout << "the length of the list is " << list.Length() << endl;
list.Print();
for(int i = 0; i < 5; i++)
{
list.Insert(3, i*3);
}
cout << "the length of the list is " << list.Length() << endl;
list.Print();
list.Remove(5);
cout << "the length of the list is " << list.Length() << endl;
list.Print();
cout << list.FindData(54)->GetData() << endl;
cout << "the third element is " << list.Get(3) << endl;
list.MakeEmpty();
cout << "the length of the list is " << list.Length() << endl;
list.Print();
return 0;
}