STL vector 和 list 的内部结构
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没有数组那么死板,一旦到达极限容量后,并不是不能加入新的元素,而是要开始进行扩容操作,就是海纳百川。
至于扩容的过程,我大致描述一下:
①开一块2old_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:需要大量的插入和删除,而不关心随即存取,数据很庞大时。
求点赞👍👍👍
原创不易,点赞容易。
您的鼓励就是我的最大动力!!!。
本篇博客到此结束,谢谢大家观看。