STL源码剖析-序列式容器之list和slist
来源:互联网 发布:p2p网络运营招聘 编辑:程序博客网 时间:2024/05/20 05:23
一.list
1.list概述
list是双向链表,对于任何位置的元素的插入或元素移除,list永远是常数时间.
2.list的节点
list本身和list节点是不同的数据结构,需要分开设计.STL list的节点结构:
template <class T> struct __list_node { typedef void* void_pointer; void_pointer next; void_pointer prev; T data; };
3.list的迭代器
STL list 是一格双向链表,迭代器必须具备前移,后移的能力,list提供的是Bidirectional Iterators.list的插入和删除操作都不会导致原来的list迭代器失效.
4.list的数据结构
STL list是一个环状双向链表,只需一个指针就可以表示整个链表.
template<class T,class Alloc = alloc> //缺省使用alloc为配置器class list{ protected : typedef __list_node<T> list_node ; public : typedef list_node* link_type ; protected : link_type node ; //只要一个指针,便可以表示整个环状双向链表 };
如果让指针node指向刻意置于尾端的一个空白节点,node便能符合STL对于"前闭后开"区间的要求,成为last迭代器.
5.insert()函数
insert()是一个重载函数,最简单的一种如下:
iterator insert(iterator position, const T& x){//在迭代器position所指位置插入一个节点,内容为x link_type tmp = create_node(x); tmp->next = position.node; tmp->prev = position.node->prev; (link_type(position.node->prev))->next = tmp; return tmp; }
6.push_back()函数
将新元素插入list尾端,内部调用insert()函数
void push_back(const T& x){ insert(end(),x); }
7.push_front()函数
将新元素插入到list头端,内部调用insert()函数
void push_front(const T&x){ insert(begin(),x); }
8.erase()函数
iterator erase(iterator position){ link_type next_node=link_type(position.node->next); link_type prev_node=link_type(position.node->prev); prev_node->next=next_node; next_node->prev=prev_node; destroy_node(position.node); return iterator(next_node); }
9.pop_front()函数
void pop_front(){ erase(begin()); }
10.pop_back()函数
移除尾节点,内部调用erase()函数
void pop_back(){ iterator i=end(); erase(--i); }
11.transfer()函数
将某连续范围的元素迁移到某个特定位置之前
void transfer(iterator position, iterator first, iterator last) { if (position != last) { (*(link_type((*last.node).prev))).next = position.node; //(1) (*(link_type((*first.node).prev))).next = last.node; //(2) (*(link_type((*position.node).prev))).next = first.node;//(3) link_type tmp = link_type((*position.node).prev); //(4) (*position.node).prev = (*last.node).prev; //(5) (*last.node).prev = (*first.node).prev; //(6) (*first.node).prev = tmp; //(7) } }
二.slist
1.slist概述
SGI STL另提供一个单向链表slist.slist和list的主要差别在于,前者的迭代器属于单向的Forward Iterator,后者的迭代器属于双向的Bidirectional iterator
根据STL的习惯,插入操作会将新元素插入于指定位置之前.作为单向链表,slist没有任何方便的方法可以回头定出前一个位置,因此它必须从头找起.
2.slist的节点
3.slist的迭代器
4.slist的数据结构
template<class T, class Alloc = alloc> class slist { public : typedef T value_type ; typedef value_type* pointer ; typedef const value_type* const_pointer ; typedef value_type& reference ; typedef const value_type& const_reference ; typedef size_t size_type ; typedef ptrdiff_t difference_type ; typedef __slist_iterator<T,T&,T*> iterator ; typedef __slist_iterator<T,const T&,const T*> const_iterator ; private : typedef __slist_node<T> list_node ; typedef __slist_node_base list_node_base ; typedef __slist_iterator_base iterator_base ; typedef simple_alloc<list_node,Alloc> list_node_allocator ; static list_node* create_node(const value_type& x) { list_node* node = list_node_allocator:;allocate() ; //配置空间 __STL_TRY{ construct(&node->data,x) ; node->next = 0 ; } __STL_UNWIND(list_node_allocator:;deallocate(node)) ; return node ; } static void destroy_node(list_node* node) { destroy(&node->data) ; //将元素析构 list_node_allocator::deallocate(node) ; //释放空间 } private : list_node_base head ; //头部。注意,它不是指针,是实物 public: slist() {head.next = 0 ;} ~slist(){clear() ;} public : iterator begin() {return iterator((list_node*)head.next) ;} iterator end() {return iteator(0) ;} iterator size() {const __slist_size(head.next) ;} bool empty() const {return head.next == 0 ;} //两个slist互换:只要将head交换互指即可 void swap(slist &L) { list_node_base* tmp = head.next; head.next = L.head.next ; L.head.next = tmp ; } public : //取头部元素 reference front() {return ((list_node*)head.next)->data ;} //从头部插入元素(新元素成为slist的第一个元素) void push_front(const value_type& x) { __slist_make_link(&head,create_node(x)) ; } //注意,没有push_back() //从头部取走元素(删除之)。修改head void pop_front() { list_node* node = (list_node*)head.next ; head.next = node->next ; destroy_node(node); } ..... } ;
5.slist的元素操作
- STL源码剖析-序列式容器之list和slist
- 【STL源码剖析读书笔记】【第4章】序列式容器之list和slist
- STL 源码剖析读书笔记五:序列式容器之 heap、priority_queue、slist
- STL源码剖析之序列容器list
- 《STL源码剖析》学习笔记之三——序列式容器(list和vector)
- 《STL源码剖析》-序列式容器(二)list容器
- STL源码剖析——序列容器之list
- STL源码剖析——序列容器之list
- STL源码剖析-序列式容器之vector
- STL源码剖析-序列式容器之deque
- STL源码剖析之slist【2013.11.26】
- STL源码剖析 - 第4章 序列式容器 - list
- STL源码剖析-序列式容器之stack和queue
- STL源码剖析-序列式容器之heap和priority_queue
- STL 源码剖析读书笔记三:序列式容器之 vector、list
- STL源码剖析之序列容器deque
- STL 源码剖析之四:序列式容器
- STL源码剖析 笔记之四 序列式容器
- 一个留着自己看的json模版
- Android 内存优化OOM 秒变大神 内存泄漏_ 性能优化(四)
- angular-ui-bootstrap-modal必须要说的几个点
- ZOJ2748-Free Kick
- 安卓的异步下载(ASYNCHTTPCLIENT以及VOLLEY)
- STL源码剖析-序列式容器之list和slist
- Mysql基础操作简单整理
- vscode 格式化json
- 机器学习笔记
- com.alibaba.fastjson.JSONArray cannot be cast to com.alibaba.fastjson.JSONObject
- hdu2199
- 仿知乎程序(三)读取webService,解析json,volley以及PullToRefreshListView的使用
- Linux部署以及启动项
- Codeforces 621D Rat Kwesh and Cheese【Long Double】