一:STL(Standard Template Library),即标准模板库,是一个高效的C++程序库
1.从实现层次看,整个 STL 是以一种类型参数化( type parameterized )的方式实现的,基于模板(template)。
2.从逻辑层次来看,在STL中体现了泛型化程序设计的思想(generic programming), 在这种思想里,大部分基本算法被抽象,被泛化,独立于与之对应的数据结构,用于以相同或相近的方式处理各种不同情形。
二:STL组件
1.Container(容器) 各种基本数据结构
2.Algorithm(算法) 各种基本算法如 sort search等
3.Iterator(迭代器) 连接containers 和 algorithms
4.了解:
Adapter(适配器) 可改变containers或function object接口的一种组件
Function object(函数对象) *
Allocator(分配器)*
三:容器
1.容器类是容纳、包含一组元素或元素集合的对象
2.七种基本容器:
向量(vector)、双端队列( deque )、链表(list) 、集合( set )、多重集合(multiset)、映射(map)和多重映射( multimap )
四:类型成员
1.循环子操作:
begin():指向第一个元素
end():指向最后一个元素的后一个位置
rbegin():指向逆序的第一个元素
rend():指向逆序的最后一个元素的后一个位置
2.访问元素操作
front():访问第一个元素
back():访问最后一个元素
[ ]:无测试的下标访问(不用于 list)
at():有测试的下标访问(只用于 vector 和 deque)
3.堆栈和队列操作
push_back():将新元素加入到尾部
pop_back():移出最后一个元素
push_front():将新元素加入头部(只用于 list 和 deque)
pop_front():移出第一个元素(只用于 list 和 deque)
4.表操作
insert(p,x):将元素x加入到 p 之前
erase(p):删除p处的元素
clear():清除所有的元素
五:迭代器
迭代器是面向对象版本的指针,它们提供了访问容器、序列中每个元素的方法
六:顺序容器
顺序容器的接口
1.插入方法:push_front(),push_back(),insert(),运算符“=”
2.删除方法:pop() ,erase(),clear()
3.迭代访问方法:使用迭代器
4.其他顺序容器访问方法(不修改访问方法):front(),back(),下标[ ]运算符
七:顺序容器--向量(vector)
a.向量属于顺序容器,用于容纳不定长线性序列(即线性群体),提供对序列的快速随机访问(也称直接访问)
b.数据结构很像一个数组,所以与其他容器相比,vector 能非常方便和高效访问单个元素,支持随机访问迭代子
c.向量是动态结构,它的大小不固定,可以在程序运行时增加或减少
d.与数组不同,向量的内存用尽时,向量自动分配更大的连续内存区,将原先的元素复制到新的内存区,并释放旧的内存区。这是向量类的优点。
头文件:#include <vector>
例子:
1.push_back尾部添加
#include<iostream>
using namespace std;
#include<vector>
void demo_vector();
int main()
{
	demo_vector();
	return 0;
}
void demo_vector()
{
	vector<int> v;
	//迭代器
	vector<int>::iterator it;
	it = v.begin(); //开始位置
   
	//在尾部添加
	v.push_back(1);
	v.push_back(12);
    //迭代器指针 遍历向量容器
	for(it = v.begin();it<v.end();it++)
	{
		cout<<" "<<*it;  //取值
	} 
	// 1 12
	cout<<endl;
}
2.insert按照位置插入
#include<iostream>
using namespace std;
#include<vector>
void demo_vector();
int main()
{
	demo_vector();
	return 0;
}
void demo_vector()
{
	vector<int> v;
	//迭代器
	vector<int>::iterator it;
    it = v.begin(); //开始位置
   
	//在尾部添加
	v.push_back(1);
	v.push_back(12);
    //按照位置插入
	v.insert(v.begin(),100);
	for(it = v.begin();it<v.end();it++)
	{
		cout<<" "<<*it;  //取值
	} 
	//  100 1 12
	cout<<endl;
}
3.获取id(成员属性)
CStaff.h
#ifndef CSTAFF_H
#define CSTAFF_H
#define ADMIN 1
#define MANAGER 2
#define WAITER 3
#include<string>
#include<iostream>
using namespace std;
class Staff
{
public:
	Staff();
	Staff(int id,string name,string pwd,int prole);
	~Staff();
	int getId();
	string getName();
	string getPwd();
	int getRole();
private:
	int ID;
	string name;
	string pwd;
	int role;
};
#endif
CStaff.cpp
#include"CStaff.h"
#include<iostream>
using namespace std;
Staff::Staff()
{
}
Staff::Staff(int id,string name,string pwd,int prole)
{
	this->ID = id;
	this->name = name;
	this->pwd = pwd;
	this->role = prole;
}
int Staff::getId()
{
	return this->ID;
}
string Staff::getName()
{
	return this->name;
}
string Staff::getPwd()
{
	return this->pwd;
}
int Staff::getRole()
{
	return this->role;
}
Staff::~Staff()
{
}
main.cpp
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
void demo_vector();
int main()
{
	demo_vector();
	return 0;	
}
void demo_vector()
{
	vector<Staff *> staffV;
	vector<Staff *>::iterator it;
	staffV.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffV.push_back(new Staff(1002,"lily","1234",ADMIN));
	staffV.insert(staffV.begin(),new Staff(1003,"sam","1234",MANAGER));
	for(it=staffV.begin();it<staffV.end();it++)
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}
//	id:1003
//  id:1001
//  id:1002
}
4.按照位置插入insert --- 需要迭代器指针it++偏移
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
void demo_vector();
int main()
{
	demo_vector();
	return 0;	
}
void demo_vector()
{
	vector<Staff *> staffV;
	vector<Staff *>::iterator it;
	staffV.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffV.push_back(new Staff(1002,"lily","1234",ADMIN));
	it = staffV.begin();  //开始位置
	it++;
	staffV.insert(it,new Staff(1003,"sam","1234",MANAGER));
	for(it=staffV.begin();it<staffV.end();it++)
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}
//id:1001
//id:1003
//id:1002
}
5.尾部删除pop_back
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
void demo_vector();
int main()
{
	demo_vector();
	return 0;	
}
void demo_vector()
{
	vector<Staff *> staffV;
	vector<Staff *>::iterator it;
	staffV.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffV.push_back(new Staff(1002,"lily","1234",ADMIN));
	it = staffV.begin();  //开始位置
	it++;
	//按照位置插入
	staffV.insert(it,new Staff(1003,"sam","1234",MANAGER));
	//尾部删除
	staffV.pop_back();
	for(it=staffV.begin();it<staffV.end();it++)
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}
//	id:1001
//  id:1003
}
6. erase按照位置删除
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
void demo_vector();
int main()
{
	demo_vector();
	return 0;	
}
void demo_vector()
{
	vector<Staff *> staffV;
	vector<Staff *>::iterator it;
	staffV.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffV.push_back(new Staff(1002,"lily","1234",ADMIN));
	it = staffV.begin();  //开始位置
	it++;
	//按照位置插入
	staffV.insert(it,new Staff(1003,"sam","1234",MANAGER));
	//尾部删除
	staffV.pop_back();
	it = staffV.begin();  //开始位置
	staffV.erase(it);//删除第一个
	for(it=staffV.begin();it<staffV.end();it++)
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}
//id:1003
}
7.erase按照位置删除(迭代器指针偏移it++)
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
void demo_vector();
int main()
{
	demo_vector();
	return 0;	
}
void demo_vector()
{
	vector<Staff *> staffV;
	vector<Staff *>::iterator it;
	staffV.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffV.push_back(new Staff(1002,"lily","1234",ADMIN));
	it = staffV.begin();  //开始位置
	it++;
	//按照位置插入
	staffV.insert(it,new Staff(1003,"sam","1234",MANAGER));
	//尾部删除
	staffV.pop_back();
	it = staffV.begin();  //开始位置
	it++;
	staffV.erase(it);//删除第二个
	for(it=staffV.begin();it<staffV.end();it++)
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}
//id:1001
}
8.size计数
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
void demo_vector();
int main()
{
	demo_vector();
	return 0;	
}
void demo_vector()
{
	vector<Staff *> staffV;
	vector<Staff *>::iterator it;
	staffV.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffV.push_back(new Staff(1002,"lily","1234",ADMIN));
	it = staffV.begin();  //开始位置
	it++;
	//按照位置插入
	staffV.insert(it,new Staff(1003,"sam","1234",MANAGER));
    cout<<"员工数量:"<<staffV.size()<<endl;
	for(it=staffV.begin();it<staffV.end();it++)
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}
//员工数量:3
//id:1001
//id:1003
//id:1002
}
9.容器访问四种
1.迭代器指针 2.at访问方式 3.[ ]中括号访问方式 4.C++新增auto访问方式
at访问方式:
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
void demo_vector();
int main()
{
	demo_vector();
	return 0;	
}
void demo_vector()
{
	vector<Staff *> staffV;
	vector<Staff *>::iterator it;
	staffV.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffV.push_back(new Staff(1002,"lily","1234",ADMIN));
	it = staffV.begin();  //开始位置
	it++;
	//按照位置插入
	staffV.insert(it,new Staff(1003,"sam","1234",MANAGER));
    cout<<"员工数量:"<<staffV.size()<<endl;
/*	for(it=staffV.begin();it<staffV.end();it++)//迭代器指针遍历
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}*/
	for(int i =0;i<staffV.size();i++)  //下标法
	{
		cout<<"id:"<<staffV.at(i)->getId()<<endl; 
	}
//员工数量:3
//id:1001
//id:1003
//id:1002
}
[ ]中括号访问方式
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
void demo_vector();
int main()
{
	demo_vector();
	return 0;	
}
void demo_vector()
{
	vector<Staff *> staffV;
	vector<Staff *>::iterator it;
	staffV.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffV.push_back(new Staff(1002,"lily","1234",ADMIN));
	it = staffV.begin();  //开始位置
	it++;
	//按照位置插入
	staffV.insert(it,new Staff(1003,"sam","1234",MANAGER));
    cout<<"员工数量:"<<staffV.size()<<endl;
/*	for(it=staffV.begin();it<staffV.end();it++)//迭代器指针遍历
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}*/
	for(int i =0;i<staffV.size();i++)  //下标法
	{
		//cout<<"id:"<<staffV.at(i)->getId()<<endl; 
		cout<<"id:"<<staffV[i]->getId()<<endl; 
	}
//员工数量:3
//id:1001
//id:1003
//id:1002
}
10.clear清空
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
void demo_vector();
int main()
{
	demo_vector();
	return 0;	
}
void demo_vector()
{
	vector<Staff *> staffV;
	vector<Staff *>::iterator it;
	staffV.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffV.push_back(new Staff(1002,"lily","1234",ADMIN));
	it = staffV.begin();  //开始位置
	it++;
	//按照位置插入
	staffV.insert(it,new Staff(1003,"sam","1234",MANAGER));
    cout<<"员工数量:"<<staffV.size()<<endl;
/*	for(it=staffV.begin();it<staffV.end();it++)//迭代器指针遍历
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}*/
	for(int i =0;i<staffV.size();i++)  //下标法
	{
		//cout<<"id:"<<staffV.at(i)->getId()<<endl; 
		cout<<"id:"<<staffV[i]->getId()<<endl; 
	}
	staffV.clear();
	 cout<<"员工数量:"<<staffV.size()<<endl;
//员工数量:3
//id:1001
//id:1003
//id:1002
//员工数量:0
}
八:顺序容器--双端队列--deque
a.双端队列是一种放松了访问权限的队列。元素可以从队列的两端入队和出队,也支持通过下标操作符“[]”进行直接访问。
b.与向量的对比 功能上:和向量没有多少区别,
性能上:在双端队列起点上的插入和删除操作快
头文件:#include <deque>
1.push_front头部插入
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
#include<deque>
void demo_deque();
int main()
{
	demo_deque();
	return 0;	
}
void demo_deque()
{
	deque<Staff *> staffV;
	deque<Staff *>::iterator it;
	staffV.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffV.push_back(new Staff(1002,"lily","1234",ADMIN));
	it = staffV.begin();  //开始位置
	it++;
	//按照位置插入
	staffV.insert(it,new Staff(1003,"sam","1234",MANAGER));
	//头部插入
	staffV.push_front(new Staff(1004,"lilei","1234",MANAGER));
    cout<<"员工数量:"<<staffV.size()<<endl;
/*	for(it=staffV.begin();it<staffV.end();it++)//迭代器指针遍历
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}*/
	for(int i =0;i<staffV.size();i++)  //下标法
	{
		//cout<<"id:"<<staffV.at(i)->getId()<<endl; 
		cout<<"id:"<<staffV[i]->getId()<<endl; 
	}
//	staffV.clear();
//	 cout<<"员工数量:"<<staffV.size()<<endl;
//员工数量:4
//id:1004
//id:1001
//id:1003
//id:1002
}
2.pop_front头部删除
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
#include<deque>
void demo_deque();
int main()
{
	demo_deque();
	return 0;	
}
void demo_deque()
{
	deque<Staff *> staffV;
	deque<Staff *>::iterator it;
	staffV.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffV.push_back(new Staff(1002,"lily","1234",ADMIN));
	//头部插入
	staffV.push_front(new Staff(1004,"lilei","1234",MANAGER));
	it = staffV.begin();  //开始位置
	//it++;
	//按照位置插入
	staffV.insert(it,new Staff(1003,"sam","1234",MANAGER));  // 3 4 1 2
	staffV.pop_front();  //头部删除
    cout<<"员工数量:"<<staffV.size()<<endl;
/*	for(it=staffV.begin();it<staffV.end();it++)//迭代器指针遍历
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}*/
	for(int i =0;i<staffV.size();i++)  //下标法
	{
		//cout<<"id:"<<staffV.at(i)->getId()<<endl; 
		cout<<"id:"<<staffV[i]->getId()<<endl; 
	}
//	staffV.clear();
//	 cout<<"员工数量:"<<staffV.size()<<endl;
//员工数量:3
//id:1004
//id:1001
//id:1002
}
九:顺序容器 --列表--list
a.链表主要用于存放双向链表,可以从任意一端开始遍历。链表还提供了拼接(splice)操作,将一个序列中的元素从插入到另一个序列中。
b.对比:元素的插入和删除操作对 list 而言尤为高效
与 vector 和 deque 相比,对元素的下标访问操作的低效是不能容忍的,因此 list 不提供这类操作。
头文件:#include <list>
list只支持迭代器法
for(it=staffList.begin();it!=staffList.end();it++)//迭代器指针遍历1.只支持迭代器指针遍历
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
#include<deque>
#include<list>
void demo_list();
int main()
{
	demo_list();
	return 0;	
}
void demo_list()
{
	list<Staff *> staffList;
	list<Staff *>::iterator it;
	staffList.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffList.push_back(new Staff(1002,"lily","1234",ADMIN));
	//头部插入
	staffList.push_front(new Staff(1004,"lilei","1234",MANAGER));
	it = staffList.begin();  //开始位置
	//it++;
	//按照位置插入
	staffList.insert(it,new Staff(1003,"sam","1234",MANAGER));  // 3 4 1 2
	staffList.pop_front();  //头部删除
    cout<<"员工数量:"<<staffList.size()<<endl;
	for(it=staffList.begin();it!=staffList.end();it++)//迭代器指针遍历
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}
//员工数量:3
//id:1004
//id:1001
//id:1002
}
2.把一个链表(单个元素)里的东西放到另外一个链表中--splice
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
#include<deque>
#include<list>
void demo_list();
int main()
{
	demo_list();
	return 0;	
}
void demo_list()
{
	list<Staff *> staffList;
  
	list<Staff *> list2;//再一个链表
	list2.push_back(new Staff(1006,"mei","1234",ADMIN));//有一个1006
	
	staffList.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffList.push_back(new Staff(1002,"lily","1234",ADMIN));
	//头部插入
	staffList.push_front(new Staff(1004,"lilei","1234",MANAGER));
    list<Staff *>::iterator it;
    it = staffList.begin();  //开始位置
	it++;                    //在第二个位置插入1006
  //splice move element from list to list
	staffList.splice(it,list2);
    cout<<"员工数量:"<<staffList.size()<<endl;
	for(it=staffList.begin();it!=staffList.end();it++)//迭代器指针遍历
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}
	cout<<"员工数量:"<<list2.size()<<endl;
//员工数量:4
//id:1004
//id:1006
//id:1001
//id:1002
//员工数量:0
}
3.把一个链表中数据(多个)放入另一个链表中(如下将list2中的1006 1007放入staffList中)
#include<iostream>
using namespace std;
#include"CStaff.h"
#include<vector>
#include<deque>
#include<list>
void demo_list();
int main()
{
	demo_list();
	return 0;	
}
void demo_list()
{
	list<Staff *> staffList;
    list<Staff *>list2;//再一链表
	list2.push_back(new Staff(1006,"mei","1234",ADMIN));  //有1006 1007
	list2.push_back(new Staff(1007,"didi","1234",ADMIN));
	staffList.push_back(new Staff(1001,"admin","1234",ADMIN));
	staffList.push_back(new Staff(1002,"lily","1234",ADMIN));
	//头部插入
	staffList.push_front(new Staff(1004,"lilei","1234",MANAGER));
 
	list<Staff *>::iterator it;
    it = staffList.begin();  //开始位置
	it++;                    //在第二个位置插入1006 1007
//splice move element from list to list
	staffList.splice(it,list2);
    cout<<"员工数量:"<<staffList.size()<<endl;
	for(it=staffList.begin();it!=staffList.end();it++)//迭代器指针遍历
	{
		cout<<"id:"<<(*it)->getId()<<endl; 
	}
	cout<<"员工数量:"<<list2.size()<<endl;
//员工数量:5
//id:1004
//id:1006
//id:1007
//id:1001
//id:1002
//员工数量:0
}










