cyclic double linked list
1. What is a circular double linked list.
Cyclic double linked list: cycle, that is, the linked list of the end to end. Double linked list, that is, on the basis of the original single linked list, so that nodes can not only point to the next node, can also point to the last node. 2. Circular double linked list basic operation (pseudo code)
List-search (L,k)
x = L.head while
x≠nil and x.key≠k
x = x.next return
x
List-insert (l,x)
X.next = L.head
If l.head = NIL
l.head.pre = x
l.head = x
x.pre = NIL
List-delete (l,x)
If X.pre = NIL
x.pre.next = x.next
Else L.head = X.next
If X.next = NIL x.next.pre
= X.pre
3. Circular double Linked list realization (C + + code)
CircularDoubleLink.h #pragma once #include <assert.h> #include <stdio.h> template<typename elemtype&
Gt Class Node {Public:node (elemtype* pData = null, node<elemtype>* Pnext = null, node<elemtype>* Pprev = NU
LL);
Elemtype const& GetData () const;
void SetData (Elemtype val);
node<elemtype>* const& GetNext () const;
void Setnext (node<elemtype>* val);
node<elemtype>* const& GetPrev () const;
void Setprev (node<elemtype>* val);
Private:elemtype* m_pdata;
node<elemtype>* M_pnext;
node<elemtype>* M_pprev;
};
Template<typename elemtype> class Circulardoublelink {public:circulardoublelink ();
unsigned int const& getlength () const;
BOOL Insert (elemtype elem, unsigned int pos);
BOOL Insertbyposnode (elemtype elem, node<elemtype>* posnode, node<elemtype>** retinsetnode = NULL);
BOOL Delete (unsigned int pos, elemtype* elem); BOOL SeaRCH (unsigned int pos, elemtype* elem) const;
BOOL Visit (elemtype* elem, const unsigned int& pos) const;
BOOL Empty ();
node<elemtype>* Havaheadnode ();
node<elemtype>* const& Getheadnode () const;
private:node<elemtype>* M_pheadnode;
unsigned int m_length;
}; The implementation of the ————————————————————————————————//node class Template<typename elemtype> Node<elemtype>::node (
elemtype* pData/* = null */, node<elemtype>* pnext/* = null */, node<elemtype>* pprev/* = NULL * */) : M_pnext (Pnext), M_pdata (PData), M_pprev (Pprev) {} template<typename elemtype> void Node<elemtype>::
Setnext (node<elemtype>* val) {m_pnext = val;} Template<typename elemtype> node<elemtype>* const& node<elemtype>::getnext () const {return M_pN
Ext
} template<typename elemtype> void Node<elemtype>::setdata (Elemtype val) {m_pdata = val;} Template<typename elemtype> Elemtype const& Node<elemtype>::getdata () const {return *m_pdata}
Template<typename elemtype> void Node<elemtype>::setprev (node<elemtype>* val) {m_pPrev = val;} Template<typename elemtype> node<elemtype>* const& node<elemtype>::getprev () const {return M_pP
Rev; }//————————————————————————————————//circulardoublelink class implements Template<typename elemtype> Circulardoublelink <elemtype>::circulardoublelink (): M_pheadnode (New Node<elemtype> ()), M_length (0) {M_pHeadNode->SetN
Ext (M_pheadnode);
M_pheadnode->setprev (M_pheadnode); } template<typename elemtype> bool Circulardoublelink<elemtype>::insertbyposnode (ElemType Elem, Node< elemtype>* Posnode, node<elemtype>** retinsetnode/*= null*/) {node<elemtype>* InsertNode = new NODE&L T
Elemtype> (New Elemtype (Elem), Posnode->getnext (), Posnode);
Posnode->getnext ()->setprev (Insertnode); Posnode->setnext (Insertnode);
++m_length;
if (retinsetnode) {*retinsetnode = Insertnode;
return true;
} template<typename elemtype> bool Circulardoublelink<elemtype>::insert (elemtype elem, unsigned int pos) { if (pos > getlength () | | pos < 0) {assert (False && "Error:singlylink ' Insert pos.
Range!\n ");
return false;
for (node<elemtype>* pcurrentnode = M_pheadnode; ; Pcurrentnode = Pcurrentnode->getnext ()) {if (pos--= 0) {Insertbyposnode (Elem, Pcurr
Entnode);
return true;
} assert (False && "Error:singlylink Insert failed for Unknow reason!");
return false;
Template<typename elemtype> bool Circulardoublelink<elemtype>::D elete (unsigned int pos, elemtype* elem) { if (POS >= getlength () | | pos < 0) {assert (false && error:singlylink ' s delete pos.
of range!\n ");
} for (node<elemtype>* Pcurrentnode = M_pheadnode->getnext ();; Pcurrentnode = Pcurrentnode->getnext ()) {if (pos--= 0) {node<elemtype>* delet
Enode = Pcurrentnode;
Deletenode->getnext ()->setprev (Deletenode->getprev ());
Pcurrentnode->getprev ()->setnext (Deletenode->getnext ());
*elem = Deletenode->getdata ();
Delete Deletenode;
--m_length;
return true;
} assert (False && "Error:singlylink POS delete failed for unknow reason!");
return false; } template<typename elemtype> unsigned int const& circulardoublelink<elemtype>::getlength () const {R
Eturn m_length; } template<typename elemtype> bool Circulardoublelink<elemtype>::search (unsigned int pos, elemtype* elem) const {if (pos >= getlength () | | pos < 0) {assert (False && "Error:singlylink's Sea")RCH Pos is out of range!\n ");
for (node<elemtype>* Pcurrentnode = M_pheadnode->getnext ();; Pcurrentnode = Pcurrentnode->getnext ()) {if (pos--= 0) {*elem = Pcurrentnode->ge
Tdata ();
return true;
return false; } template<typename elemtype> bool Circulardoublelink<elemtype>::visit (elemtype* elem, const unsigned int& Amp
POS) Const {if (pos >= getlength () | | pos < 0) {return false;
Return Search (Pos,elem);
} template<typename elemtype> bool Circulardoublelink<elemtype>::empty () {return!m_length;} Template<typename elemtype> node<elemtype>* Circulardoublelink<elemtype>::havaheadnode () {return
M_pheadnode; Template<typename elemtype> node<elemtype>* const& circulardoublelink<elemtype>:: Getheadnode () const {return M_pheadnode}
//util.h #pragma once namespace Util {template<typename t> void printmemory (const
t& datestruct, unsigned int size) {cout << "printmemory:";
for (int i = 0; I!= size; i++) {Elemtype tempelem;
if (!datestruct.visit (&tempelem,i)) {printf ("\ n");
Return
printf ("%d", Tempelem);
printf ("\ n"); }
}
Main.cpp #include "Util.h" #include "CircularDoubleLink.h" #include <iostream> using namespace std;
typedef int ELEMTYPE;
int main () {circulardoublelink<int> testcirculardoublelink; cout << "Testcirculardoublelink is" << (Testcirculardoublelink.empty ()?) Empty. ":" Not Empty. ")
<< Endl;
Util::P rintmemory (Testcirculardoublelink,testcirculardoublelink.getlength ());
for (int i = 0; I!= 5; i++) {Testcirculardoublelink.insert (i+1,i);
cout << "\ninsert:" << i << Endl; cout << "Testcirculardoublelink is" << (Testcirculardoublelink.empty ()?) Empty. ":" Not Empty. ")
<< Endl;
Util::P rintmemory (Testcirculardoublelink,testcirculardoublelink.getlength ());
for (int i = 0; I!= 2; i++) {Elemtype tempelem;
Testcirculardoublelink.delete (I,&tempelem);
cout << "\ndelete:" << tempelem << Endl; cout << "Testcirculardoublelink is" << (Testcirculardoublelink.empty ()?) Empty. ":" Not Empty. ")
<< Endl;
Util::P rintmemory (Testcirculardoublelink,testcirculardoublelink.getlength ());
return 0; }
3. Results of program Operation
Testcirculardoublelink is Empty.
Printmemory:
insert:0
Testcirculardoublelink is not Empty.
Printmemory:1
Insert:1
Testcirculardoublelink is not Empty.
Printmemory:1 2
Insert:2
Testcirculardoublelink is not Empty.
Printmemory:1 2 3
Insert:3
Testcirculardoublelink is not Empty.
Printmemory:1 2 3 4
Insert:4
Testcirculardoublelink is not Empty.
Printmemory:1 2 3 4 5
Delete:1
Testcirculardoublelink is not Empty.
Printmemory:2 3 4 5
Delete:3
Testcirculardoublelink is not Empty.
Printmemory:2 4 5