算法导论 循环双链表
来源:互联网 发布:数据库参照完整性约束 编辑:程序博客网 时间: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: 1Insert:1
testCircularDoubleLink is Not Empty.
PrintMemory: 1 2Insert:2
testCircularDoubleLink is Not Empty.
PrintMemory: 1 2 3Insert:3
testCircularDoubleLink is Not Empty.
PrintMemory: 1 2 3 4Insert:4
testCircularDoubleLink is Not Empty.
PrintMemory: 1 2 3 4 5Delete:1
testCircularDoubleLink is Not Empty.
PrintMemory: 2 3 4 5Delete:3
testCircularDoubleLink is Not Empty.
PrintMemory: 2 4 5
0 0
- 算法导论 循环双链表
- 算法导论 循环单链表
- 算法导论 顺序循环队列
- 算法导论 顺序循环双向队列
- 算法导论 第二章 循环不变式(loop invariant)
- 算法导论-循环不变式、插入排序、归并排序
- 「算法导论」:到底什么是循环不变式?
- 算法导论 32.4-5 字符串的循环旋转问题
- 算法导论学习-数学归纳法与循环不变式理解
- 《算法导论》
- 《算法导论》
- 算法导论
- 算法导论
- 算法导论
- 算法导论
- 算法导论
- 算法导论
- 算法导论
- Varnish Configuration Language - VCL(varnish配置语言-VCL)
- java 查看内存
- MessageQueue.IdleHandler接口使用方法以及原理分析
- Android5.0源码开发之修改Button大小写
- 黑马程序员-Java基础学习第三天总结
- 算法导论 循环双链表
- init 6 和reboot
- postgreSQL学习问题之一
- 相关分析
- Android Activity launchMode研究
- 程序员必须知道的10大基础实用算法及其讲解
- shell和mysql使用总结
- Js/Jquery获取iframe中的元素
- CNN的学习资料