sgi stl 之list
来源:互联网 发布:free mobile java护士 编辑:程序博客网 时间:2024/05/18 02:36
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而是data pointer operator->() const { return &(operator*()); } //++i self& operator++() { node = node->next; return *this; } //i++ self operator++(int) { self tmp = *this; ++(*this); return tmp; } //--i self& 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); else first = 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
就是用counter[64]表示一个进制为2^64的大数,同样,这个算法可以排序的最大结点数是2^64 - 1
while(i < fill && !counter[i].empty())
可以看做是一个加1操作,从低位开始进位
- sgi stl 之list
- SGI-STL学习笔记之list::sort()
- list (仿sgi stl)
- SGI STL: list::sort()算法
- SGI STL源码之vector
- STL 中的List排序算法(in SGI STL)
- SGI-STL学习笔记之allocator
- SGI-STL学习笔记之heap算法
- SGI-STL学习笔记之IntroSort
- SGI-STL学习笔记之IntroSort
- SGI-STL学习笔记之allocator .
- SGI STL 源码解读之Allocator
- SGI STL 源码解读之 Iterator
- SGI STL源码解读之 string
- SGI STL 之空间配置器
- sgi stl中list的sort函数实现
- SGI STL序列式容器list中的sort算法
- sgi stl中list的sort函数实现
- Yaffs2 文件系统移植
- java动态代理学习笔记
- Linux ALSA声卡驱动之四:Control设备的创建
- 查看mysql字符集及修改表结构
- C/C++宏定义的可变参数
- sgi stl 之list
- 点两次back键退出程序
- WIZnet将出席国际集成电路中国展会(IIC China)(明日开幕)
- svn: Malformed network data
- ios之Label的创建
- Eclipse RCP 从菜单打开Editor
- 修改mysql默认字符集的方法
- 点云匹配介绍
- sqlserver 查询通配符