vector容器
vector是一个顺序性容器,相当于一个能动态调整大小数组,从内存上来说,vector的动态调整是指,当所需内存无法满足时,会重新开辟一块大约两倍于原来内存大小的空间,并将之前的数据拷贝过去,因此正常情况下,vector容器的capcity()通常会大于他的size()。
vector的用法
vector<type> name;
创建对象
vector容器与数组类似,是支持随机访问的。需要通过STL中内置的迭代器iterator来访问,iterator的性质与使用方法类似与指针
vector<int>::iterator it;
创建一个迭代器
同时STL又许多内置函数方便使用,下面是一些比较基础且常用的:
name.push_back()//往容器依次插入数据
name.pop_back()//删除容器中最后一个数据
name.begin()//指向容器中第一个数据的位置
name.end()//指向容器中最后一个数据的下一个位置
name.front()//访问容器中的第一个元素
name.back()//访问容器中最后一个元素
name.insert(iterator,elem);//从迭代器指向的位置插入指定元素
name.erase(iterator-1,iterator-2)//删除从迭代器1到迭代器2位置的所有数据
name.clear()//清空容器中所有数据
name1.swap(name2)//交换两个容器的大小,巧用swap可以有效收缩内存空间
name.capcity()//容器内存大小
name.size()//容器中数据多少
name.reserve(num)//预留容器空间,动态开辟空间时常用
本身vector就与array非常类似,因此也支持像数组一样的方式的随机访问;
//用[ ]访问元素
for (int i = 0; i < v1.size(); i++)
{
cout << v1[i] << " ";
}
当方法上要比array多样化很多:
//用at访问元素
for (int i = 0; i < v1.size(); i++)
{
cout << v1.at(i) << " ";
}
一个简单的循环输出容器中的内容,原理上与指针输出类似:
for(vector<int>::iterator it=v.begin(); it!=v.end(); it++)
{
cout << *it << " " ;
}
list容器
list,即为列表,是通过双向链表的方式实现的,与vector相比,最大的差异就是不能随机存取,只能顺序存取
因此,他的用法大致上也与vector相差不大
list的用法
list<type> name;//创建对象
list常用api:
name.push_front()//头部插入数据
name.push_back()//尾部插入数据
name.pop_front()//头部删除
name.pop_back()//尾部删除
name.reverse()//整个列表反转
name.sort()//排序
name.begin()//指向容器中第一个数据的位置
name.end()//指向容器中最后一个数据的下一个位置
name.front()//访问容器中的第一个元素
name.back()//访问容器中最后一个元素
。。。。。。
由此可以看出list的内置函数只要不涉及底层构成,例如不支持随机访问等,其他基本都是一样的。
stack容器
stack容器,也就是我们熟悉的“栈”
这个容器的使用就与上面两个容器有些许不同,身为栈,自然是严格遵守先进后出的原则,且只能从栈顶出栈
下面是从内置函数的角度来体现栈的特性
stack的用法
stack<type> name;//创建对象
常用内置函数:
name.push()//入栈
name.pop()//出栈
name.top()//栈顶元素
name.size()//栈的大小级栈内元素个数
name.empty()//栈内为空
name.swap(name2)//与name2栈交换元素
。。。。。。
由于栈本身数据结构的限制,其他容器中很多内置函数,stack容器中是无法使用的,例如排序,反转,随机插入等。
queue容器
queue容器,顾名思义,也就是所谓的队列,因此,和stack一样,自然也是严格遵守相应的数据结构,即队列的数据结构:先进先出,队头出队,队尾入队等原则。
queue的用法
queue<type> name;//创建对象
常用内置函数:
name.push()//入队
name.pop()//出队
name.front()//队头元素
name.back()//队尾元素
name.size()//队长,即对内元素个数
name.empty()//队内为空
name.swap(name2)//与name2队交换元素
。。。。。。
由于队列与栈独特的结构,虽然与其他容器之间,在函数上有较大区别,但是我们观察一下就不难发现,这两个容器的内置函数却是几乎一模一样。因此这两种容器结合起来学习会简单许多。
deque容器
deque为双向队列,即可以在队列的两端进行元素的插入和删除操作,除此之外,大部分规则都与queue容器相类似。
deque的用法
deque<type> name //创建对象
name.push_front()//头插
name.push_back()//尾插
name.pop_front()//头删
name.pop_back()//尾删
name.insert(iterator,num,para)//在迭代器的位置插入num个para
name.front()//队头元素
name.back()//队尾元素
。。。。。。
由于deque身为双端队列,操作起来要比普通的队列要方便许多。因此,在内置函数方面,也要比普通队列可以使用的内置函数要更多一些,操作更加便捷。
set/multiset容器
set与multiset是两个相对紧密相关却又不完全相同的的容器。首先两个容器最大的特点也是共同点,就是他们会对容器内的元素进行自动排序。不同之处在于set容器内不允许出现重复的值,而multiset是允许容器内出现重复值的。
set/multiset的用法、
set/multiset<type> name;创建对象
name.insert()//插入元素
name.find()//返回目标元素所在迭代器位置
name.count()//返回目标元素存在数量
。。。。。。
由于容器本身会对内部元素默认进行升序排序,因此,可以在定义容器时,通过仿函数定义对应的排序规则以满足我们的需求:
如图所示,即通过简单的仿函数将排序方式改变成降序排列。
map/multimap容器
map与multimap容器时诸多容器中较为特殊,他是以键值对的方式存在并使用的,就像python中的字典一样,一个元素分为key值与value值。
map/multimap从形式上就可以看出与set/multiset必有关联。诚然,map/multimap也是会自动排序的,当然因为其键值对的形式,因此只会根据key值进行默认的升序排序,区别也与set/multiset相同,只是体现在value部分:map中不允许出现value重复的元素,而multimap允许出现重复value的元素。
map/multimap的用法
map/multimap<type1,type2> name;//创建对象
name.insert(pair<type1,type2>(para1,para2))//插入元素
map/multimap<type1,type2> name2(name);//将name的全部赋值给name2
map/multimap<type1,type2> name3;name3=name2 //将name2的元素全部赋值给name3
。。。。。。
与set容器一样,既然容器会对内部元素进行自动排序,那么当然可以通过仿函数改变其中的排序规则:
以上就是我对学习的STL容器的一点总结。