算法导论 循环双链表

来源:互联网 发布:数据库参照完整性约束 编辑:程序博客网 时间:2024/06/06 01:15

循环双链表

1. 什么是循环双链表?

循环双链表:循环,即是首尾相连的链表。双链表,即是在原来单链表的基础上,使结点不单只能指向下一个结点,也能指向上一个结点。

2. 循环双链表的基本操作(伪代码)

LIST-SEARCH(L,k)

x = L.headwhile x ≠NIL and x.key ≠ kx = x.nextreturn x

LIST-INSERT(L,x)

x.next = L.headif L.head = NILL.head.pre = xL.head = xx.pre = NIL

LIST-DELETE(L,x)

if x.pre = NILx.pre.next = x.nextelse L.head = x.nextif x.next = NILx.next.pre = x.pre

3. 循环双链表的实现(C++代码)

//CircularDoubleLink.h#pragma once#include <assert.h>#include <stdio.h>template<typename ElemType>class Node{public:    Node(ElemType* pData = NULL, Node<ElemType>* pNext = NULL, Node<ElemType>* pPrev = NULL);    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;};//————————————————————————————————//Node类的实现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_pNext;}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_pPrev;}//————————————————————————————————//CircularDoubleLink类实现template<typename ElemType>CircularDoubleLink<ElemType>::CircularDoubleLink()    :m_pHeadNode(new Node<ElemType>()),m_length(0){    m_pHeadNode->SetNext(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<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's insert pos is out of range!\n");        return false;    }    for(Node<ElemType>* pCurrentNode = m_pHeadNode;         ; pCurrentNode = pCurrentNode->GetNext())    {        if (pos-- == 0)        {            InsertByPosNode(elem, pCurrentNode);            return true;        }    }    assert(false && "Error: SinglyLink Insert failed for unknow reason!");    return false;}template<typename ElemType>bool CircularDoubleLink<ElemType>::Delete(unsigned int pos, ElemType* elem){    if (pos >= GetLength() || pos < 0)    {        assert(false && "Error: SinglyLink's delete pos is out of range!\n");    }    for(Node<ElemType>* pCurrentNode = m_pHeadNode->GetNext(); ;         pCurrentNode = pCurrentNode->GetNext())    {        if (pos-- == 0)        {            Node<ElemType>* deleteNode = 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{    return 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 search pos is out of range!\n");    }    for(Node<ElemType>* pCurrentNode = m_pHeadNode->GetNext(); ;        pCurrentNode = pCurrentNode->GetNext())    {        if (pos-- == 0)        {            *elem = pCurrentNode->GetData();            return true;        }    }    return false;}template<typename ElemType>bool CircularDoubleLink<ElemType>::Visit(ElemType* elem, const unsigned int& 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 oncenamespace 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::PrintMemory(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::PrintMemory(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::PrintMemory(testCircularDoubleLink,testCircularDoubleLink.GetLength());    }    return 0;}

3. 程序运行结果

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

0 0
原创粉丝点击