sgi stl 的list实际上是一个双向环形链表

下面是代码

#ifndef C_LIST_H
#define C_LIST_H
#include "cconstruct.h"
#include "cvector.h"template <class T>
struct list_node {typedef list_node<T>* point;point prev;point next;T data;
};template <class T, class Ref, class Ptr>
struct list_iterator {typedef list_iterator<T, T&, T*> iterator;typedef list_iterator<T, Ref, Ptr> self;typedef bidirectional_iterator_tag iterator_category;typedef ptrdiff_t distance_type;typedef T value_type;typedef Ref reference;typedef Ptr pointer;typedef list_node<T>* link_type;//指向list_node的指针,所谓list_iterator也指向list_node的指针link_type node;list_iterator(){}list_iterator(link_type x):node(x) {}list_iterator(iterator& x):node(x.node) {}bool operator==(const self& x) const { return node == x.node; }bool operator!=(const self& x) const { return node != x.node; }reference operator*() const {return (*node).data;}//list_iterator表示指针,*point 表示取得这个指针所指之物,指向的不是list_node而是datapointer operator->() const { return &(operator*()); }//++iself& operator++() {node = node->next;return *this;}//i++self operator++(int) {self tmp = *this;++(*this);return tmp;}//--iself& operator--() {node = node->prev;return *this;}//i--self operator--(int) {self tmp = *this;--(*this);return tmp;}
};template <class T, class Alloc = alloc>
class clist {
protected:typedef T vale_type;typedef T* pointer;typedef T& reference;typedef list_node<T> list_node;typedef list_node* link_type;typedef simple_alloc<list_node, Alloc> list_node_allocator;public:typedef list_iterator<T, T&, T*> iterator;typedef list_iterator<T, const T&, const T*> const_iterator;public:iterator begin() { return node->next; }const_iterator begin() const{ return node->next; }iterator end() {return node;}const_iterator end() const{ return node; }bool empty() const { return node->next == node; }size_t size()  const{size_t len = 0;const_iterator it;for (it = begin(); it != end(); ++it)++len;return len;}reference front() { return *begin(); }reference back() { return *(--end()); }protected://获得一块结点的内存link_type get_node() { return list_node_allocator::allocate(); }//释放一个节点的内存void put_node(link_type p) { list_node_allocator::deallocate(p); }//构造一个节点link_type create_node(const T& x) {link_type p = get_node();construct(&p->data, x);return p;}void destroy_node(link_type p) {destroy(&p->data);put_node(p);}void empty_initialize() {node = get_node();node->next = node;node->prev = node;}
public:clist() { empty_initialize(); }~clist() {clear();destroy_node(node);}iterator insert(iterator position, const T& x) {link_type tmp = create_node(x);tmp->next = position.node;tmp->prev = position.node->prev;position.node->prev->next = tmp;position.node->prev = tmp;return tmp;}void push_back(const T& x) { insert(end(), x); }void pop_back() {erase(--end());}void pop_front() {erase(begin());}void push_front(const T& x) { insert(begin(), x); }iterator erase(iterator position) {position.node->prev->next = position.node->next;position.node->next->prev = position.node->prev;destroy_node(position.node);return position.node->next;}void clear() {iterator currNode = begin();while ( currNode != end()) {destroy_node((currNode++).node);}node->next = node;node->prev = node;}void remove(const T& x) {iterator first = begin();iterator last = end();while (first != last) {if (*first == x)erase(first++);else++first;}}//这个算法的思路很清晰void unique() {iterator first = begin();iterator last = end();if (first == last) return ;iterator next = first;while (++next != last ) {if (*first == *next)erase(next);elsefirst = next;next = first;}}void splice(iterator position, clist&, iterator i) {iterator j = i;++j;if (j == position || i == position) return;transfer(position, i, j);}//将[first, last) 放入position之前,[first, last) 可以和position在同一链表或不同链表,但是区间和position不能重叠void transfer(iterator position, iterator first, iterator last) {if (position != last) {first.node->prev->next = last.node;position.node->prev->next = first.node;last.node->prev->next = position.node;link_type tmp = position.node->prev;position.node->prev = last.node->prev;last.node->prev = first.node->prev;first.node->prev = tmp;}}void merge(clist<T, Alloc>& x) {iterator first1 = begin();iterator last1 = end();iterator first2 = x.begin();iterator last2 = x.end();while (first1 != last1 && first2 != last2) {if (*first2 < *first1) {iterator next = first2;transfer(first1, first2, ++next);first2 = next;}else {++first1;}}if (first2 != last2) transfer(last1, first2, last2);}void reverse() {if (node->next == node || node->next->next == node) return;iterator first = begin();++first;while(first != end()) {iterator old = first;++first;transfer(begin(),old, first);}}void swap(clist<T, Alloc>& x) {std::swap(node, x.node);}void sort() {if (node->next == node || node->next->next == node) return;clist<T, Alloc> carry;clist<T, Alloc> counter[64];int fill = 0;while ( !empty()) {carry.splice(carry.begin(), *this, begin());//carry = 1;可以认为是carry每次都赋值为1,counter是一个大数,能够表示2^64进制的数。while的过程就是counter加1的过程int i = 0;while(i < fill && !counter[i].empty()) {counter[i].merge(carry);carry.swap(counter[i++]);}carry.swap(counter[i]);if (i == fill)++fill;}for (int i = 1; i < fill; ++i)counter[i].merge(counter[i-1]);swap(counter[fill-1]);}protected:link_type node;//用此指针指向环状链表
};#endif

其中比较难理解的list中快速排序的实现,其实更像是归并排序

就是用counter[64]表示一个进制为2^64的大数,同样,这个算法可以排序的最大结点数是2^64 - 1

while(i < fill && !counter[i].empty())

可以看做是一个加1操作,从低位开始进位

sgi stl 之list相关推荐

  1. SGI STL 内存分配方式及malloc底层实现分析

    在STL中考虑到小型区块所可能造成的内存碎片问题,SGI STL设计了双层级配置器,第一级配置器直接使用malloc()和free();第二级配置器则视情况采用不同的策略:当配置区块超过128byte ...

  2. SGI STL 学习笔记二 vector

    sequence containers Array Vector Heap Priority_queue List sList(not in standard) Deque Stack Queue S ...

  3. 栈与队列在SGI STL的底层实现

    栈 栈提供push和pop等接口,不提供走访功能,也不提供迭代器. STL中栈不被归类为容器,而被归类为container adapter(容器适配器),这是因为栈是以底层容器完成其所有的工作,对外提 ...

  4. 【STL深入学习】SGI STL空间配置器详解(二)-第二级空间配置器

    本文讲解SGI STL空间配置器的第二级配置器. 相比第一级配置器,第二级配置器多了一些机制,避免小额区块造成内存的碎片.不仅仅是碎片的问题,配置时的额外负担也是一个大问题.因为区块越小,额外负担所占 ...

  5. 【STL深入学习】SGI STL空间配置器详解(一)-第一级空间配置器

    一.SGI STL配置器简介 SGI STL的配置器与众不同,它与标准规范不同.如果要在程序中明确使用SGI配置器,那么应该这样写: vector<int,std::alloc> iv; ...

  6. SGI STL allocator

    简单实现是一个allocator C++模板及实现vector_~怎么回事啊~的博客-CSDN博客 SGI STL包含了一级空间配置器和二级空间配置器,其中一级空间配置器allocator采用mall ...

  7. 剖析SGI STL空间配置器(空间配置器的重要性和重要成员及函数)

    剖析SGI STL空间配置器 在我们使用STL容器的时候,模板最后一个参数会有一个默认的allocator作为容器模板的参数,这个参数就是STL的空间配置器.容器的空间配置器见这篇文章:容器空间配置器 ...

  8. 有关SGI STL的alloc

        在STL的使用者层面上,空间配置器一般是隐藏的,使用者不需要知道其具体实现细节即 可进行使用:但是从STL的实现角度来说,由于整个STL的操作对象都存放在容器之内,而容器 需要配置一定的空间来 ...

  9. 深度剖析SGI STL二级空间配置器内存池源码

    文章目录 一.SGI STL二级空间配置器重要成员解读 二. 二级空间配置器内存池的结构 三. 两个重要的函数 1. _S_round_up 2. _S_freelist_index 四. 内存池al ...

最新文章

  1. Redis 笔记(11)— 文本协议 RESP(单行、多行字符串、整数、错误、数组、空值、空串格式、telnet 登录 redis)
  2. Error:(49, 1) A problem occurred evaluating project ':guideview'. Could not read script 'https://r
  3. Java多线程系列--“基础篇”10之 线程优先级和守护线程
  4. 设计有setAll功能的哈希表
  5. 使用SpringTask定时获取传感器设备信息并缓存到Redis
  6. hdu 4585 Shaolin set
  7. 29. ExtJs - Struts2 整合(1) - 登录页面
  8. python实现单例模式的三种方式及相关知识解释
  9. mac上的mysql管理工具sequel pro
  10. 从一线技术人员到阿里合伙人,主导了去“IOE”,没有他,阿里只能给美国公司打工!...
  11. showdoc windows 搭建_showdoc的安装和使用
  12. 低代码工具是软件维护的噩梦?
  13. WINDOW7下 配置APACHE+PHP 无法加载MYSQL 的问题
  14. 2017-09-20 前端日报
  15. 常用的各种标准下载网站(HB GB GJB MH)
  16. 3t studio 导出数据_Studio 3T下操作MongoDB的基本命令(转载)
  17. 阿里云ACE备考题库161-240
  18. html img图片不变形等比例缩放,兼容ie6
  19. 竟然在GitHub标星27k+阿里大牛肝出的443页TCP/IP协议趣谈笔记,有何神奇之处?
  20. 惠普笔记本恢复出厂系统

热门文章

  1. 十七、去年jQuery的笔记
  2. 做时间序列预测有必要用深度学习吗?梯度提升回归树媲美甚至超越多个DNN模型...
  3. 今日arXiv精选 | 11篇EMNLP 2021最新论文
  4. 对比学习可以使用梯度累积吗?
  5. 3天造了一个深度学习轮子,生猛!
  6. L0对抗攻击JSMA的算法盘点
  7. 一文详解支持向量机(SVM)
  8. 在物体检测任务上进行预训练的实验分析
  9. 砸了140亿的计算机视觉,未来到底如何?
  10. 数字图像处理与Python实现笔记之频域滤波