- vector
1.1 构造函数:
1.2 erasevector():start(0),finish(0),end_of_storage(0){} //start表示目前使用空间的头,finish表示目前使用空间的尾,end_of_storage表示目前可使用空间的尾 vector(size_type n,const T& value) {fill_initialize(n,value);} void fill_innitialize(size_type n,const T& value) { start=allocate_and_fill(n,value); finish=start+n; end_of_storage=finish; } iterator allocate_and_fill(size_type n,const T& x) { iterator result=data_allocator::allocate(n); //配置n个元素空间 uninitialized_fill_n(result,n,x); //根据第一形参的型别特性(type traits)决定使用fill_n()或反复调用construct() return result; } vector(int n,const T& value) {fill_initialize(n,value);} vector(long n,const T& value) {fill_initialize(n,value);} explicit vector(size_type n) {fill_initialize(n,T());}
1.3 对vector的任何操作,一旦引起空间重新配置,指向元vector的所有迭代器就都失效了iterator erase(iterator position) //清除某个位置上的元素 { if(position +1 != end()) copy(position+1,finish,position); --finish; destroy(finish); return position; } iterator erase(iterator first, iterator last) //清除[first,last)的所有元素 { iterator i=copy(last,finish,first); destroy(i,finsih); finish=finish-(last-first); return first; }
1.4 vector的insert返回值是void - list
2.1 list的插入和接合(splice)都不会使原来的迭代器失效,删除也只会使指向被删除元素的迭代器失效
2.2
2.3 list的插入在指定迭代器之前,返回指向新插入元素的迭代器_list_node<T>* node; //list列表的节点 T& operator* ()const {return (*node).data;} T* operator-> ()const {return &(operator*());} //迭代器的成员存取运算子的标准做法
2.4 erase删除迭代器的值返回的是该迭代器的next迭代器
2.5 remove将数值为value的所有元素移除
2.6 移除数值相同的连续元素,注意,只有连续而相同的元素才会被移除剩一个template<class T,class Alloc> void list<T,Alloc>::remove(const T& value) { iterator first=begin(); iterator lase=end(); while(first!=last) { iterator nexe=first; ++next; if(*first==value) erase(first); first=next; } }
2.7 splice
2.7.1 void splice(iterator position,list& x); //将x接合于position所指位置之前,x必须不同于*this
2.7.2 void splice(iterator position,list& x,iterator first,iterator last); //将[first,last)接合于position所指位置之前,position和[first,last)可以指向同一个list,但position不能在[first,last)之内
2.8 merge之前要保证先排好序 - deque
3.1 deque与vector的区别一是deque允许在常数时间内对头端的元素进行插入或删除;二是deque没有容量概念。除非必要,我们应该尽可能使用vector,对deque进行的排序操作,为了提高效率,可将deque先完整复制到一个vector身上,将vector排序后再复制回deque - stack和queue
4.1 stack和queue没有迭代器,没有遍历功能
4.2 可以更换容器,比如queue<int,list< int >> iqueue; - binary heap是一种完全二叉树
5.1 push_heap,将新元素插在底层vector的end()处,将新节点与其父节点比较,如果其键值比父节点大,就父子对换位置,如此一直上溯,直到不需要对换或者到根节点为止
5.2 pop_heap, STL默认是max-heap,最大值必然在根节点,pop操作取走根节点后,为了满足完全二叉树的条件,必须割舍最下层最右边的叶节点,并将其值重新安插在max-heap。将空间节点和其较大子节点对调,并持续下放,直到叶子节点为止。注意,pop_heap之后,最大元素只是被置于底部容器的最尾端,尚未被取走。如果要取其值,可使用底部容器(vector)的back()函数,如果要移除它,可使用vector提供的pop_back()函数
5.3 创建大大根堆: 我们假设根节点的索引为1。
5.3.1.从最后一个非叶子节点为父节点的子树出发,从右往左,从下往上进行调整操作,这里需注意的是:
a.是以该非叶子节点为父节点的子树,即该父节点以下的所有部分都进行调整操作。
b.由于是从右往左从下往上,则某一步进行调整时在调整它之前的那些子树已经是堆有序了,即走到某个非叶子节点时,它的子树已经是堆有序了(因为是从下往上)
5.3.2.即调整函数 :
a.如果该节点比它的两个孩子节点都大,则该节点不用调整了,因为它的孩子节点也是堆有序 (上面b已说明)
b.如果该节点比它的两个子节点中的较大节点小,即array[i]<max(array[2i],array[2i+1]),将 array[i]赋给temp,以后每次都跟temp比较。将max(array[2i],array[2i+1])赋给array[i]。接着从max(array[2i],array[2i+1]) 对应的那个节点出发,继续进行该操作,直到该节点到达了n。当然每次判断边界条件为左子树的索引小于n,则右子树才有值。
5.4 priority_queue< int > xxx 大根堆
priority_queue<int, vector< int >, greater< int >> xxxx 小根堆 - slist:单向链表
6.1 作为一个单向链表,slist没有任何方便的办法可以回头定出前一个位置,因此它必须从头找起。换句话说,除了slist起点附近的区域之外,在其他位置上采用insert或erase操作函数,都属不智之举。
6.2 slist没有push_back和pop_back ,只有push_front 和 pop_front
STL源码剖析笔记 —— 第四章
最新推荐文章于 2020-04-06 22:43:31 发布