数据结构与算法分析(c++版) #6 双链表
2015-09-18 19:20
344 查看
双链表
单链表只允许从一个表结点直接访问它的后继结点,而双链表可以从一个表结点出发,在线性表中随意访问它的前驱结点和后继接电脑。双链表存储两个指针,使这些成为可能:一个智指向它的后继结点(与单链表相同),另一个指向它的前驱结点。如下图:
![](http://img.blog.csdn.net/20150918193027057?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
下面是双链表的结点类实现:
而对于链表类的实现,只需改变insert,append,remove,prev函数即可:
单链表只允许从一个表结点直接访问它的后继结点,而双链表可以从一个表结点出发,在线性表中随意访问它的前驱结点和后继接电脑。双链表存储两个指针,使这些成为可能:一个智指向它的后继结点(与单链表相同),另一个指向它的前驱结点。如下图:
下面是双链表的结点类实现:
template <class Elem> class Node { private: static Node<Elem>* freelist; // 空闲表 public: Elem element; // 该结点的值 Node* next; // 指向下一个结点 Node* prev; // 两个构造函数 Node(const Elem& elemval, Node* preval = nullptr, Node* nextval = nullptr) { element = elemval; prev = preval; next = nextval; } Node(Node* preval = nullptr, Node* nextval = nullptr) { prev = preval; next = nextval; } // 重载操作符 void* operator new(size_t); void operator delete(void*); }; template <class Elem> Node<Elem>* Node<Elem>::freelist = nullptr; template <class Elem> void* Node<Elem>::operator new(size_t) { // 如果空闲表为空,调用系统的new创建一个Node对象 if (freelist == nullptr) return ::new Node; Node<Elem>* temp = freelist; freelist = freelist->next; return temp; } template <class Elem> void Node<Elem>::operator delete(void* ptr) { ((Node<Elem>*)ptr)->next = freelist; freelist = (Node<Elem>*)ptr; }
而对于链表类的实现,只需改变insert,append,remove,prev函数即可:
// 在右表最前面插入元素 template <class Elem> bool DLList<Elem>::insert(const Elem& item) { // 在栅栏后插入新结点,把新结点的next指向栅栏后一个结点,prev指向栅栏,再把本身的地址附给栅栏后面 fence->next = new Node<Elem>(item, fence, fence->next); // 如果新结点不是最后一个结点,就把后一个结点的prev指向新结点 if (fence->next->next != nullptr) fence->next->next->prev = fence->next; if (tail == fence) tail = fence->next; ++rightcnt; return true; } // 在右表末尾拼接元素 template <class Elem> bool DLList<Elem>::append(const Elem& item) { tail = tail->next = new Node<Elem>(item, tail, nullptr); ++rightcnt; return true; } // 删除右表第一个元素 template <class Elem> bool DLList<Elem>::remove(Elem& item) { // 右表为空 if (fence->next == nullptr) return false; // 读出要删除的值 item = fence->next->element; // 创建临时结点 Node<Elem>* ntemp = fence->next; // 如果右表只剩下最后一个元素 if (ntemp->next != nullptr) ntemp->next->prev = fence; else tail = fence; fence->next = ntemp->next; delete ntemp; --rightcnt; return true; } // 把栅栏的位置向左移动一个单位,如果栅栏已经是表头就不移动 template <class Elem> void DLList<Elem>::prev() { if (fence != head) { fence = fence->prev; --leftcnt; ++rightcnt; } }双链表与单链表相比唯一的缺点就是使用更多的空间需求。双链表的每一个结点需要两个指针。这种实现方法,它需要的结构性开销是单链表的两倍。
相关文章推荐
- 数据结构与算法分析(c++版) #5 可利用空间表提高链表效率
- 软测试-数据结构
- 数据结构学习5--树(二)之排序二叉树(中)
- 数据结构学习4--树(二)之排序二叉树(上)
- 算法与数据结构笔记
- 数据结构学习4--树(一)
- Libevent数据结构分析
- 从B树、B+树、B*树谈到R 树
- 数据结构 list map set
- 栈的应用-迷宫问题-数据结构
- 关于数据结构的学习经验分享 (二叉树相关的内容)
- soj.1003 hit or miss
- 二叉查找树及遍历算法
- 数据结构中的常用查找
- 数据结构实验二:双向链表
- 数据结构之快速排序
- 数据结构实验二:循环链表
- 数据结构实验二:单链表
- 【数据结构】线性表的链式存储结构--单链表
- 数据结构分类