STL vector 和 list 的内部结构分析

24 篇文章 0 订阅
5 篇文章 0 订阅


vector: (俗称: 动态数组)

vector使用方式

#include <vector>		//要先含入vector的头文件
#include <algorithm>
int main(){
	//每次创建一个vector对象需要给一个泛型,指定vector存储的数组类型
	
	//以下演示三种创建vector的方法
	vector<string> sv;	//调用无参构造函数,创建一个空的vector 名字为sv
	vector<string> sv1(10);	//调用有参构造函数,创建了一个空间大小为10,初值为空串的vector
	vector<string> sv2(10,"1");	//调用有参构造函数,创建了一个空间大小为10,初值为"1“的vector
	
	string s1="A";
	//插入操作
	sv.push_back(s1); 	//同样,也可以写成sv.push("A");效果是一样的;
	//大小
	sv.size();
	//暂时就说这两个操作
	reutrn 0;
}

vector内部结构分析

vector被称为动态数组的原因:

数组:
①地址是连续的,而且是顺序存储,可以通过下标访问,访问某个元素的时间复杂度是O(1)
②众所周知,我们定义一个数组的时候必须给定一个数组的最大容量capacity,创建数组的时候大小不能被改变。

vector:
①vector也是顺序存储,开辟一段连续的空间存储数据,vector重载了[]运算符,不仅可以通过他自身特有的使用迭代器iterator来访问元素,也可以和数组一样可以通过下标访问,访问某个元素的时间复杂度与数组一样,只需要O(1)的时间。
②我想说的是这个地方,以下解释动态,vector的源码中这样写到:

一段vector源码:

//当即将插入一个元素,检测到vector已经达到了capacity,相当于一个数组达到了max_size。
const size_type old_size=size();
const size_type len=  old_size!=0?2*old_size:1;

接上文:
第一行:先记录下原来vector的capacity(容量)
第二行:当capacity不为0的时候 把原空间2,扩容两倍 (如果是0则把空间设为1)
这两句话已经可以看出来,vector没有数组那么死板,一旦到达极限容量后,并不是不能加入新的元素,而是要开始进行扩容操作,就是海纳百川。
至于扩容的过程,我大致描述一下:
①开一块2
old_size空间 s
②把old_vector的元素迁移过新的空间 s中
③释放原来空间
大致可以这么描述,当然不会特别准确。

list: (其实是一种双向循环链表)

list使用方式:

#include<list>
#include <algorithm>

int main(){
	//以下演示三种创建list的方法
	list<string> list_s;			//调用无参构造函数,创建一个空的list 名字为sv
	list<string> list_s2(10);		//调用有参构造函数,创建了一个空间大小为10,初值为空串的list
	list<string> list_s3(10,"AAA");	//调用有参构造函数,创建了一个空间大小为10,初值为"1“的vector
	iterator::list<string> it=s.begin():
	//在某个位置插入   ,两个参数,第一个参数是一个迭代器,描述位置,第二个参数则是值
	list_s.inset(it,"keep on going, never give up!");
	return 0;
}

list (双向循环链表) 内部结构分析:

数据结构之链表:

学过数据结构的同学都知道,链表分为很多种,(序号越大越麻烦。。)
①单链表
②双链表
③单向循环链表
④双向循环链表
没错,最终结果就是,list采用的就是最复杂的链表
4号选手-双向循环链表,其实这么设计的好处有很多。
一段源码(描述结点的结构):

template <class T>
struct _list_node{
	typedef void* void_pointer;	//参照 侯捷大师的说法:如果让老师看见你写void* 是不得分的,
	//不要出现void*类型,这里个人认为最好是改写成:_list_node<T>*
	//相信我们在大学的时候老师也是这么教的
	void_pointer prev;
	void_pointer next;
};

vector与list使用时机0

list在任何插入元素,不需要像vector一样移动数据,只需要修改指针即可,复杂度始终为O(1),在这个操作中比vector优秀。

而访问数据的时候vector支持下标访问,也就是随机访问,而list不支持,访问每个元素都要对list进行遍历。在这点上vector比list优秀。

如果对象很庞大时,vector一旦达到最大容量会以两倍扩容,这样就会非常浪费空间,list只是再增加一个结点的空间,这点list比vector优秀。

结论:

vecotr:要高效的随即存取,而不在乎插入和删除的效率,数据少时。
list:需要大量的插入和删除,而不关心随即存取,数据很庞大时。


求点赞👍👍👍
原创不易,点赞容易。
您的鼓励就是我的最大动力!!!。
本篇博客到此结束,谢谢大家观看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值