找工作之STL源码

来源:互联网 发布:服务器网络拓扑图图片 编辑:程序博客网 时间:2024/06/10 21:21

临时对象的产生和运用(仿函数和算法的搭配)
for_each(iv.begin(),iv.end(),print());
空间配置器:为什么不是内存配置器(allocator),可以是磁盘或者其他辅助存储介质。
new包含两阶段的内容,先调用operator new 配置内存,然后调用构造函数
配置器分两级(可以避免太多小额区块造成的碎片):
当分配的内存超过128bytes,用第一级配置器,其作用是malloc和free作用一样;
当分配的内存小于128bytes,用第二级配置器,采用内存池管理,每次配置一大块内存,并维护对应的自由链表,维护16个freelists,各自管理大小为8,16,24,32…128bytes的小额区块。
STL的中心思想是将数据容器(class templates)和算法(function templates)分开,彼此独立设计,然后用胶着剂将两者撮合起来。
迭代器是一种智能指针,C++里有auto_ptr
智能指针:它的一种通用实现方法是采用引用计数的方法。智能指针将一个计数器与类指向的对象相关联,引用计数跟踪共有多少个类对象共享同一指针。
每次创建类的新对象时,初始化指针并将引用计数置为1;
当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;
对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;这是因此左侧的指针指向了右侧指针所指向的对象,因此右指针所指向的对象的引用计数+1;
调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)
traits的目的是:让属于同一个概念的、具有不同特性的模型,对外暴露一致的接口。
Iterator
5类 其中包括input iterator,output iterator,forward iterator, Bidirectional iterator, Random iterator.前3类只支持operator++,第四类支持operator–,最后一类包含所有指针算术能力。
实现iterator的工作:
1.定义5类迭代器的标志类,该标志类用于实现函数的区别调用(即重载),例如求两迭代器距离函数distance(iter1,iter2,tag),移动函数advance(iter,n,tag)。这五个标志类分别为:input_iterator_tag,output_iterator_tag,forward_iterator_tag,bidirectional_iterator_tag,random_access_iterator_tag。
2.对于每一个iterator类,都必须包含5个属性,分别为:iterator_category、value_type、difference_type、pointer、reference。
3.定义一个迭代器的“属性榨汁机”iterator_traits,用于获取iterator的5种属性值。
4.定义迭代器的操作,分别为:
1) 获取iterator的标志—–>iterator_category(iter);
2)获取两迭代器差值的类型—–>distance_type(iter);
3)获取迭代器的原始类型———>value_type(iter);
4)求两迭代器的距离—————->distance(iter1,iter2,tag);
5)将迭代器移动n位——————>advance(iter,n,tag)。

序列式容器
vector list(slist) deque
配接器 stack queue(没有迭代器)
Vector优势是高效随机存取(随机迭代器)
List 用于需要大量进行插入和删除的情况(双向迭代器)
Deque 随机存取 两端进行插入,删除(随机迭代器)
Deque没有容量概念,它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来,不会出现vector重新分配空间并复制元素的情况。Iterator中包括cur,first,last,node指针。
Max堆和Min堆(堆排序:建堆;调整堆;排序(每次交换根元素与末端元素再进行调整))
Priority_queue的所有元素,进出都有一定的规则,只有queue顶端的元素(权值最高者),才有机会被外界取用。

关联式容器
set map multiset multimap底层机制均用RB-tree
另外底层机制为hash table有hash_set,hash_map等等。
RB-tree平衡二叉搜索树(还有AVL树)
判断是否平衡
class Solution {
public:
bool isBalanced (TreeNode* root) {
return balancedHeight (root) >= 0;
}
/**
* Returns the height of root if root is a balanced tree,
* otherwise, returns -1.
*/
int balancedHeight (TreeNode* root) {
if (root == nullptr) return 0; // 终止条件
int left = balancedHeight (root->left);
int right = balancedHeight (root->right);
if (left < 0 || right < 0 || abs(left - right) > 1) return -1; // 剪枝
return max(left, right) + 1; // 三方合并
}
};
RB-tree满足以下规则:
每个节点不是黑色就是红色;
根节点为黑色;
如果节点为红色,其子节点必须为黑色;
任意节点至NULL(树尾端)的任何路径,所含黑节点的个数必须相同。

Set的实值就是键值,所有元素都会根据元素的键值自动被排序
通过set的迭代器不改变set的元素值 改变其值,会破坏set的排序,其实现方式是通过const_iterator,杜绝写入操作。
Multiset允许键值重复:插入操作采用的是RB-tree的insert_eaual()而非insert_unique()

Hashtable
在插入,删除,搜寻等操作上具有“常数平均时间”
使用某种映射函数,将大数映射为小数,这个小数作为索引的位置。可能不同的元素映射到相同的位置,解决碰撞的方法:线性探测,二次探测,开链法。

0 0
原创粉丝点击