C++容器内部实现

1.vector底层实现

        其底层数据结构是动态数组,由于数组的特点,vector也具有以下特性:
        1、O(1)时间的快速访问;
        2、顺序存储,所以插入到非尾结点位置所需时间复杂度为O(n),删除也一样;

        通过这 3 个迭代器,就可以表示出一个已容纳 2 个元素,容量为 5 的 vector 容器。

  • _Myfirst 和 _Mylast 可以用来表示 vector 容器中目前已被使用的内存空间;
  • _Mylast 和 _Myend 可以用来表示 vector 容器目前空闲的内存空间;
  • _Myfirst 和 _Myend 可以用表示 vector 容器的容量。

        扩容规则

        当我们新建一个vector的时候,如std::vector vec,会首先分配给他一片连续的内存空间,再通过vec.push_back()向其中增加元素. 当初始分配空间已满,就会引起vector扩容, 默认容量是0, 之后插入按照1 2 4 8 16 倍扩容。GCC是二倍扩容,VS13是1.5倍扩容。扩容后是一片新的内存,需要把旧内存空间中的所有元素都拷贝进新内存空间中去,之后再在新内存空间中的原数据的后面继续进行插入构造新元素,并且同时释放旧内存空间,并且,由于vector 空间的重新配置,导致旧vector的所有迭代器都失效了。

        注意:

        这种格式不被允许,当vector被初始化时,未访问的空间不能进行复制操作,以免超出系统内部分配的空间而出现问题。

void vector_test() {

	vector<int> vec;

	vec.push_back(2);
	vec.push_back(6);

	vector<int>::iterator it;

	for (int i = 0;i < 5;i++) vec[i] = i;

	cout << vec[5] << endl;
}

2.deque底层实现

       vector容器是单向开口的连续内存空间,deque 则是一种双向开口的连续线性空间。所谓的双向开口,意思是可以在头尾两端分别做元素的插入和删除操作,vector 容器也可以在头尾两端插入元素,但是在其头部操作效率奇差。

        deque与vector一样,底层实现是数组。和 vector 容器采用连续的线性空间不同,deque 容器存储数据的空间是由一段一段等长的连续空间构成,各段空间之间并不一定是连续的,可以位于在内存的不同区域。

void deque_test() {

	deque<int> deq;

	deq.push_back(56);
	deq.push_front(8);
	deq.pop_back();
	deq.pop_front();

	deque<int> deq2(5, 8);  // 赋初值5个8
	for (deque<int>::iterator it = deq2.begin(); it != deq2.end();it++) {
		cout << *it << endl;
	}

	deque<int>::iterator it = deq.begin();
	deq.insert(it, 5, 45);

	cout << deq.at(1) << endl;  // deq.at()与deq[]的区别在于可以检查是否越界

	deq.clear();
}

3.map底层实现

        map的底层实现采用的就是一种非常高效的平衡检索二叉树:红黑树完成的。

        ps:multimap允许同一个键,不同的值存在。

        关于红黑树的详细解说:

void map_test() {
	map<int, string> person;

	person.insert(pair<int, string>(1, "555"));
	person.insert(map<int, string>::value_type(6, "96"));
	person[21] = "sdja";

	pair <map< int, string > ::iterator, bool > insert_pair;

	insert_pair = person.insert(map<int, string>::value_type(5, "415"));

	if (!insert_pair.second)
		cout << "insert eror" << endl;

	map<int, string>::iterator iter;
	iter = person.find('1');

	if (iter != person.end()) {
		cout << "find the dic" << endl;
		person.erase(iter);
	}
	else {
		cout << "find error" << endl;
	}

	person.erase(person.begin(), person.end());

}

4. list底层实现
 

        由于 list 容器的元素并不是连续存储的,所以该容器迭代器中,必须包含一个可以指向 list 容器的指针,可以双向的操作容器内的数据。

void list_test() {
	
	list<int> li;

	li.push_back(5);
	li.push_front(6);

	list<int>::iterator it;
	
	for (it = li.begin();it != li.end();it++) {
		cout << int(*it) << endl;
	}

	li.reverse();
	li.clear();
}

5.set底层实现

        set作为一个容器是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。应该注意的是set中数元素的值不能直接被改变。

        ps:multiset允许容器里面存储的值重复。

        set的底层实现是通过红黑树完成的。

void set_test() {

	set<int> s;
	
	s.insert(5);
	s.insert(8);
	s.insert(96);

	int max_value = s.max_size();
	int begin = *s.begin();
	int end = *s.end();

	s.clear();

	set<int>::iterator it;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值