1.标准模板库
定义:标注模板库 惠普实验室开发的一些列统称
组成部分:
容器:特殊的数据机构用来存放数据。
迭代器:用来遍历,底层是一些列的指针组成。用来通过迭代器操作容器
算法:多容器的算法操作,排序,查找等操作
空间配置器:管理模块类
配接器: 仿函数: 对象( 参数)
组件的关系:各个部分组成的关系
容器:容器是用来存放数据的,和数据结构中的队列 双向链表栈!
2..vector--- 动态数组
连点: 顺序存放 ,可以改变数组大小,数组在尾部添加和移除数据非常快,但是在中间或者头部添加删除数据就比较慢了。
可以不指定大小,直接使用
构造: 无参构造: vector<类型> 对象;
有参构造:vector(size_t n,T x); 用n个x构建数组。
vector<int> v(2,10);
拷贝构造 :vector(const T& X);
vector<int> x(v);
迭代器:iterator 是一种可以变量容器元素的数据类型(理解成内部类)。可以理解成容器和操作容器算法的中间。
begin() 迭代器执行容器的首位置
end() 迭代器执行容器的尾位置下一个
迭代器定义格式: vector<int>::iterator it = arr.begin();
成员函数:
size() --- 获取vector的元素个数
案例:vec.size() 一般用于for循环中
clear(); 清空vector中的内容,size变成0,capacity不会变
empty(); 判断vector是否为空,如果为空则结果为真
insert(迭代器位置,值):在某一个位置插入值,底层会把所有位置后的数据往后移动,效率比较低下
erase(): 删除vector的一个数据或者某一个范围的数据
第一种:删除某一个数据 vector.erase(迭代器位置) 删除迭代器位置的元素
第二种:删除某一个范围的数据 案例
vector.erase(vc.begin(),vc.begin()+4),会删除第一个到第三个元素,第四个元素不会删除;
push_back();在尾部添加一个元素,效率比较高。参数是需要添加的值
pop_back(); 在尾部删除一个元素,没有返回值
capacity():得到vector的容量,可以使用的总大小。
代码:程序作用 定义一个学生的结构体,有姓名年龄,学生id。(用vector存放数据)
如果输入1则尾部添加一个学生,输入2则打印学生信息,输入3则随机位置插入学生信息,输入4则班级解散。
头文件
student.h
#ifndef STUDENT_H
#define STUDENT_H
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
using namespace std;
typedef struct student
{
int id;
string name;
}stu;
void caidan(vector<stu>&q);
void zuoyong1(vector<stu> &q,stu a);//尾部添加学生信息
void zuoyong2(vector<stu> &q);//打印学生信息
void zuoyong3(vector<stu> &q,stu a,int n);//随机位置插入学生信息
void zuoyong4(vector<stu> &q);//清空学生信息
#endif // STUDENT_H
student.cpp
#include "student.h"
void caidan(vector<stu> &q)
{
int a;
cout<<"请输入您的选择:";
cin>>a;
if(a==1)
{
stu b;
cout<<"请输入学生的id:";
cin>>b.id;
cout<<"请输入学生的name : ";
cin>>b.name;
zuoyong1(q,b);
}
if(a==2)
{
zuoyong2(q);
}
if(a==3)
{
stu b;
int n;
cout<<"请输入学生的id:";
cin>>b.id;
cout<<"请输入学生的name : ";
cin>>b.name;
cout<<"请输入插入的数据: ";
cin>>n;
zuoyong3(q,b,n);
}
if(a==4)
{
zuoyong4(q);
}
}
void zuoyong1(vector<stu> &q,stu a)//尾部添加学生信息
{
q.insert(q.end(),a);//地址 ++ 数据
getchar();
caidan(q);
}
void zuoyong2(vector<stu> &q)//打印学生信息
{
vector<stu>::iterator it =q.begin();
for(it=q.begin();it!=q.end(); it++)//it++ 遍历下一个
{
cout<<"学生的id : "<<it->id<<" ";
cout<<"学生的名字: "<<it->name<<endl;
}
getchar();
caidan(q);
}
void zuoyong3(vector<stu> &q,stu a,int n)//随机位置插入学生信息
{
q.insert(q.begin()+n,a);
getchar();
caidan(q);
}
void zuoyong4(vector<stu> &q)//清空学生信息
{
q.clear();
getchar();
caidan(q);
}
main.cpp
#include <iostream>
#include <vector>
#include<list>
#include<cstdlib>
#include"student.h"
#include"bank.h"
using namespace std;
void show(vector<int> &vec1)//打印动态数组的元素
{
//begin() 是开始!
//end() 是结束!
vector<int>::iterator it =vec1.begin();
for(it=vec1.begin();it!=vec1.end(); it++)//it++ 遍历下一个
{
cout<<*(it)<<" ";
}
cout<<"元素的个数: "<<vec1.size()<<endl; //获得元素个数
}
int main(int argc, char *argv[])
{
/*
vector<int>vec1;//无参构造
vector<int>vec2(5,10);//有参构造 ,4个 int 类型的数值 10存入动态数组
vec1=vec2;//拷贝构造
show(vec1);
vec1.pop_back();//尾部删除
show(vec1);
vec1.clear();//清空动态数组 vector
//判断动态数组 vector 是否为空
if(vec1.empty())
{
cout<<"vector 是空的!"<<endl;
}
else
{
cout<<"vector 不是空的!"<<endl;
}
//插入数据
vec1.insert(vec1.end(),110);//地址 ++ 数据 //这里插入的数据是哪里 就插入哪里, begin() -》下标为 0 的位置
show(vec1);
//在任意的位置删除元素
vec1.erase(vec1.begin());//括号里面的数据是 迭代器的地址
show(vec1);
//vec2 插入数据
vec2.insert(vec2.begin(),110);
show(vec2);
//删除固定范围的数据
vec2.erase(vec2.begin(),vec2.begin()+1);//前面那个数据不会删除,1 2 3 4 的动态数组只会删除 1 第一个数据, 因为begin 是开始的 0 吧!
show(vec2);
//开始的时候申请的空间大小,是开始申请的2 倍,等空间不够的时候再次申请!!
cout<<"容量空间大小: "<<vec2.capacity()<<endl;//容量空间
*/
//建立动态数组
vector<stu> q;
//运用菜单
caidan(q);
return 0;
}
3.list(双向链表)
头文件: #include<list>
特点: list是双向链表,在任意位置添加和删除都方便,效率高,但查找不容易,不可以通过下标操作。
构造:
第一个:空的构造函数 list()
第二个: 拷贝构造 list(const list& other)
第三个:list(int n,T val); 包含n个val元素
第四个:用某一个容器的某一部分进行构造
list(T first,T last) 包含[ first ,last)
成员函数:
首元素: front()
尾元素: back()
判断空:empty()
得大小: size()
清空: clear()
尾部添加:push_back()
尾部删除: pop_back()
头部添加: push_front()
头部删除:pop_front()
添加元素: insert()
交换list: swap()
链表排序: sort()
链表反转: reverse()
代码:程序 功能: 测试list 的函数
main.c
#include <iostream>
#include <vector>
#include<list>
#include<cstdlib>
#include"student.h"
#include"bank.h"
using namespace std;
int main(int argc, char *argv[])
{
list<int>mylist1;//无参构造
list<int>mylist2(5,6);//有参构造 定义 5个 6
list<int>mylist3(mylist2);//拷贝构造
vector<int>vct(10,20);
list<int>mylist4(vct.begin()+3,vct.end()-2);//拷贝了5个! 20
cout<<mylist3.size()<<endl;//元素个数
mylist3.pop_front();//头部删除
mylist1.insert(mylist1.begin(),111);//任意位置添加元素
mylist1.reverse();//list 反转
mylist1.swap(mylist3);//list 的相互交换
mylist1.sort();//排序函数 固定的升序
// 第一个地址 第二个地址
mylist1.erase(mylist1.begin(),mylist1.end());//list 的开始位置,到list 末尾的位置,全部删除
return 0;
}
4.deque(双向队列)
队列特点:先进先出
deque是在vector和list的组合,可以在两端push和pop
可以随机访问的,可以使用下标操作,等价vector中的at。
常用函数
deque.assign(begin(),end()) 赋值 把[begin,end)的数据赋值给deque
deque.assign(n,val) ; 把n个val赋值给deque
deque.at(x), 得到下标是x的数据元素,如果越界会抛出异常out_of_rang
deque.back() ; 得到最后一个元素
deque.front(); 得到首元素
deque.begin() 迭代器,指向首元素
deque.end() ;迭代器中执行尾元素
deque.clear() 清空队列
deque.size() 得到队列的容器
deque.push_back(val) 尾部添加
deque.pop_back() 尾部删除
deque.push_front() 头部添加
deque.rbegin(); 反向迭代器,指向最后一个,it++ 指向倒数第二个
deque.resize() 重新指定长度, 返回实际长度大小
代码:
#include <iostream>
#include <deque>
using namespace std;
void show(deque<int> de)//打印队列数据
{
deque<int>::const_reverse_iterator it = de.rbegin();
while (it != de.rend())
{
cout << *it << " ";
it++;
}
cout << "\n-------------------"<<endl;
}
int main()
{
deque<int> de;//无参构造
for (int i = 0;i < 5;i++)
de.push_back(i);//尾部添加数据
de.assign(5, 10);//把5 个 10 的值赋给 de
show(de);
de.pop_front();//头部删除
show(de);
cout << de.at(1) << endl;
de.resize(100);
show(de);
de.clear();
show(de);
return 0;
}
5.set(集合)
作用:叫做集合,容器中不允许有相同的数据,并且数据自动排序。
底层叫红黑树的平衡二叉树(红黑树) 也是一种容器
代码:
#include <iostream>
#include <set>
using namespace std;
void show(set<int> de)
{
set<int>::iterator it = de.begin();
while (it != de.end())
{
cout << *it << " ";
it++;
}
cout << "\n-------------------" << endl;
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,98,90 };
//把数组中所有元素添加到 set中
set<int> myset(arr,arr+sizeof(arr)/sizeof(arr[0]));
myset.insert(911);
set<int>::iterator it = myset.begin();
//c++的新语法
for (auto& i : myset)
{
cout << i << endl;
}
show(myset);
myset.erase(5);
show(myset);
try{
set<int>::const_iterator cit = myset.find(9011);
}
catch (...)
{
// cout << *cit << endl;
}
std::cout << "Hello World!\n";
}
6. map(字典--地图)
特点:字典--一个key值对应一个val,由两个部分组成。
map则需要添加key也需要添加val所以要在map中放pair模板类
map可以方便的查找,并且key是唯一的。
底层是二叉树实现的。每次插入值的时候都需要重写构建一个树
pair构造:
无参构造:std::pair<key,val> x;
有参构造:std::pair<key ,val> x(begin,end);
拷贝构造:std::pair<key,val> x(const std::pair<key,val>& other);
map的构建:
map<string,int> xxx;
map成员函数
添加数据:需要添加pair模板, insert(pair<key,val>(1,2));
begin(): 迭代器第一元素
end() :迭代器最后一个元素
at(int pos): 访问pos位置的元素
rbegin() 反向迭代器
erase(): 删除一个元素或者某个范围的元素,不可以使用反向迭代器
size(): map的大小,实际存放数据元素
find(key) 查找key对应的值,返回的是迭代器。
map中有两个成员变量,一个是first一个second ,迭代器中的first表示key,second表示val
可以通过下标访问元素。也可以通过下标赋值,但下标是key。
代码:
#include <iostream>
#include <map>
using namespace std;
int main()
{
map<int, string> mymap;//建立一个 map key 是 int 类型 val 是 string 类型
mymap.insert(pair<int, string>(11, "ddanny1"));
mymap.insert(pair<int, string>(2, "ddanny2"));
mymap.insert(pair<int, string>(13, "ddanny3"));
mymap.insert(pair<int, string>(1, "ddanny4"));
mymap.insert(make_pair(6, "ddanny"));
for (map<int, string>::iterator it = mymap.begin();
it != mymap.end();it++)
{
cout << it->first<<": "<< it->second << endl;
}
//最大可以使用的map大小。
cout << mymap.max_size() << endl;
mymap[2] = "abc";
//下标是key 所以13是key
cout << mymap[13] << endl;
cout << mymap.at(1) << endl;
mymap[1] = mymap[2];
cout << mymap[1] << endl;
mymap.clear();//清除
}
7.queue 操作
queue 和 stack 有一些成员函数相似,但在一些情况下,工作方式有些不同:
- front():返回 queue 中第一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。
- back():返回 queue 中最后一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。
- push(const T& obj):在 queue 的尾部添加一个元素的副本。这是通过调用底层容器的成员函数 push_back() 来完成的。
- push(T&& obj):以移动的方式在 queue 的尾部添加元素。这是通过调用底层容器的具有右值引用参数的成员函数 push_back() 来完成的。
- pop():删除 queue 中的第一个元素。
- size():返回 queue 中元素的个数。
- empty():如果 queue 中没有元素的话,返回 true。
- emplace():用传给 emplace() 的参数调用 T 的构造函数,在 queue 的尾部生成对象。
- swap(queue<T> &other_q):将当前 queue 中的元素和参数 queue 中的元素交换。它们需要包含相同类型的元素。也可以调用全局函数模板 swap() 来完成同样的操作。
代码:
#include <cstdlib>
#include <iostream>
#include <queue>
using namespace std;
int main()
{
int e,n,m;
queue<int> q1;//创建队列
for(int i=0;i<10;i++)
q1.push(i); //入队
if(!q1.empty())//判断是否为空
cout<<"dui lie bu kong\n";
n=q1.size();//返回队列元素的数量
cout<<n<<endl;
m=q1.back();//返回队列最后的元素
cout<<m<<endl;
for(int j=0;j<n;j++)
{
e=q1.front();//返回队列开始的元素
cout<<e<<" ";
q1.pop();//出队
}
cout<<endl;
if(q1.empty())
cout<<"dui lie bu kong\n";
system("PAUSE");
return 0;
}
8.stack
一:头文件
#include<stack>
二:定义stack
stack<int> s;创建一个空的 stack 对象。
stack<int, list<int> > s1;
stack<int, list<int> > s2(s1);
利用 s1 ,创建一个以双向链表为底层容器的空堆栈对象 s2 。
三:基本函数
empty() 堆栈为空则返回真
pop() 移除栈顶元素
push() 在栈顶增加元素
size() 返回栈中元素数目
top() 返回栈顶元素
swap()交换元素
四:用法示例
#include <iostream>
#include <stack>
#include <vector>
#include <string>
using namespace std;
int main() {
int i = 0;
stack<int> v;
for (i=0;i<10;++i)
{
v.push(i);
cout << v.top() << "已入栈"<<endl;
}
cout << "现在栈的容量" << v.size() << endl;
for (i=0;i<10;++i)
{
cout << v.top() << "准备出栈" << endl;
v.pop();
}
cout << "现在栈的容量" << v.size() << endl;
return 0;
}