一、STACK容器
1.stack容器基本概念
-
stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口
-
栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为
-
栈中进入数据称为 — 入栈
push
-
栈中弹出数据称为 — 出栈
pop
2.stack容器常用接口
函数原型:
构造函数:
stack<T> stk;
stack采用模板类实现, stack对象的默认构造形式。stack(const stack &stk);
拷贝构造函数。
赋值操作:
stack& operator=(const stack &stk);
重载等号操作符。
数据存取:
push(elem);
向栈顶添加元素。pop();
从栈顶移除第一个元素。top();
返回栈顶元素。
大小操作:
empty();
判断堆栈是否为空。size();
返回栈的大小。
#include <queue>
#include<iostream>
using namespace std;
void test(){
stack<int> s;
s.push(10);
s.push(20);
s.push(30);
s.push(40);
while (!s.empty()){
cout << "yuansu: " << s.top() << endl;
s.pop();
}
cout << "daixao: " << s.size() << endl;
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
二、QUEUE容器
1.queue容器基本概念
-
Queue是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口
-
队列容器允许从一端新增元素,从另一端移除元素
-
队列中只有队头和队尾才可以被外界使用,因此队列不允许有遍历行为
-
队列中进数据称为 — 入队
push
-
队列中出数据称为 — 出队
pop
2.queue容器常用接口
函数原型:
构造函数:
queue<T> que;
queue采用模板类实现,queue对象的默认构造形式。queue(const queue &que);
拷贝构造函数。
赋值操作:
queue& operator=(const queue &que);
重载等号操作符。
数据存取:
push(elem);
往队尾添加元素。pop();
从队头移除第一个元素。back();
返回最后一个元素。front();
返回第一个元素。
大小操作:
empty();
判断堆栈是否为空。size();
返回栈的大小。
#include <queue>
#include <string>
#include<iostream>
using namespace std;
class Person{
public:
Person(string name, int age){
this->name= name;
this->age = age;
}
string name;
int age;
};
void test(){
queue<Person> s;
Person p1("hh", 18);
Person p2("hh", 19);
Person p3("hh", 20);
Person p4("hh", 21);
s.push(p1);
s.push(p2);
s.push(p3);
s.push(p4);
cout << "daixao: " << s.size() << endl;
while (!s.empty()){
cout << "shou: " << s.front().name<<" " <<s.front().age<< endl;
cout << "wei: " << s.back().name << " " << s.back().age << endl;
s.pop();
}
cout << "daixao: " << s.size() << endl;
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
三、LIST容器
1.list容器基本概念
- 功能:将数据进行链式存储
链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的
链表的组成:链表由一系列结点组成
结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域
STL中的链表是一个双向循环链表
由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器
list的优点:
- 采用动态存储分配,不会造成内存浪费和溢出
- 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
list的缺点:
- 链表灵活,但是空间(指针域) 和 时间(遍历)额外耗费较大
list有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的
STL中List和vector是两个最常被使用的容器
2.list容器构造函数
函数原型:
-
list<T> lst;
list采用采用模板类实现,对象的默认构造形式。 -
list(beg,end);
构造函数将[beg, end)区间中的元素拷贝给本身。 -
list(n,elem);
构造函数将n个elem拷贝给本身。 -
list(const list &lst);
拷贝构造函数。
#include<iostream>
#include <list>
using namespace std;
void print(const list<int>v1){
for (list<int>::const_iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test(){
list<int> l1;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
l1.push_back(40);
print(l1);
list<int>l2(l1.begin(), l1.end());
print(l2);
list<int>l3(l2);
print(l3);
list<int>l4(1, 10);
print(l4);
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
3.list容器赋值和交换操作
函数原型:
-
assign(beg, end);
将[beg, end)区间中的数据拷贝赋值给本身。 -
assign(n, elem);
将n个elem拷贝赋值给本身。 -
list& operator=(const list &lst);
重载等号操作符 -
swap(lst);
将lst与本身的元素互换。
#include<iostream>
#include <list>
using namespace std;
void print(const list<int>v1){
for (list<int>::const_iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test(){
list<int> l1;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
l1.push_back(40);
print(l1);
list<int>l2;
l2 = l1;
print(l2);
list<int>l3;
l3.assign(l2.begin(), l2.end());
print(l3);
list<int>l4;
l4.assign(4, 10);
print(l4);
l1.swap(l4);
print(l1);
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
4.list容器大小操作
函数原型:
-
size();
返回容器中元素的个数。 -
empty();
判断容器是否为空。 -
resize(num);
重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。 -
resize(num, elem);
重新指定容器的长度为num,若容器变长,则以elem值填充新位置。
#include<iostream>
#include <list>
using namespace std;
void print(const list<int>v1){
for (list<int>::const_iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test(){
list<int> l1;
if (l1.empty()) cout << "empty" << endl;
else cout << "not empty" << endl;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
l1.push_back(40);
print(l1);
if (l1.empty()) cout << "empty" << endl;
else {
cout << "not empty" << endl;
cout << "个数:" << l1.size() << endl;
}
l1.resize(10, 100);
print(l1);
l1.resize(2);
print(l1);
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
5.list容器插入和删除
函数原型:
-
push_back(elem);
在容器尾部加入一个元素。 -
pop_back();
删除容器中最后一个元素。 -
push_front(elem);
在容器开头插入一个元素。 -
pop_front();
从容器开头移除第一个元素。 -
insert(pos,elem);
在pos位置插elem元素的拷贝,返回新数据的位置。 -
insert(pos,n,elem);
在pos位置插入n个elem数据,无返回值。 -
insert(pos,beg,end);
在pos位置插入[beg,end)区间的数据,无返回值。 -
clear();
移除容器的所有数据。 -
erase(beg,end);
删除[beg,end)区间的数据,返回下一个数据的位置。 -
erase(pos);
删除pos位置的数据,返回下一个数据的位置。 -
remove(elem);
删除容器中所有与elem值匹配的元素。
#include<iostream>
#include <list>
using namespace std;
void print(const list<int>v1){
for (list<int>::const_iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test(){
list<int> l1;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
print(l1);
l1.push_front(100);
l1.push_front(200);
l1.push_front(300);
print(l1);
l1.pop_back();
l1.pop_front();
print(l1);
list<int>::iterator it = l1.begin();
l1.insert(++it, 1000);
it = l1.begin();
l1.insert(it, 3, 2000);
print(l1);
l1.erase(it);
print(l1);
/*l1.erase(l1.begin(), l1.end());
print(l1);*/
l1.remove(2000);
print(l1);
l1.clear();
print(l1);
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
6.list容器数据存取
函数原型:
-
front();
返回第一个元素。 -
back();
返回最后一个元素。
#include<iostream>
#include <list>
using namespace std;
void print(const list<int>v1){
for (list<int>::const_iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test(){
list<int> l1;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
print(l1);
/*l1[0]; //list容器不支持[]方式访问数据
l1.at(1);//list容器不支持at方式访问数据*/
cout << "first:" << l1.front() << endl;
cout << "last:" << l1.back() << endl;
list<int>::iterator it = l1.begin();
/*it + 1;//list容器不支持跳跃访问
(应为不支持+数字防止加上大于1的数字,所以直接一刀切)*/
it++;
it--;//这两种方式则可以
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
7.list容器反转和排序
函数原型:
-
reverse();
反转链表。 -
sort();
链表排序。
#include<iostream>
#include <list>
using namespace std;
void print(const list<int>v1){
for (list<int>::const_iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
bool Compare(int v1, int v2){
return v1 > v2;
}
void test(){
list<int> l1;
l1.push_back(10);
l1.push_back(30);
l1.push_back(20);
print(l1);
l1.reverse();
print(l1);
l1.sort();
print(l1);
l1.sort(Compare);//其本身原理就是默认放进一个从小到大排序的函数,
//所以可以往里面放进一个其他函数改变排序顺序
print(l1);
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
8.list容器自定义数据排序
#include<iostream>
#include<string>
#include <list>
using namespace std;
class Person{
public:
int age;
string name;
int height;
Person(string name, int age, int height){
this->age = age;
this->name = name;
this->height = height;
}
};
bool ComparePerson(Person &p1,Person &p2){
if (p1.age == p2.age) return p1.height > p2.height;
else return p1.age < p2.age;
}
void test(){
list<Person> l1;
Person p1("aa", 10, 190);
Person p2("bb", 10, 160);
Person p3("cc", 10, 180);
Person p4("dd", 12, 190);
Person p5("ee", 12, 140);
Person p6("ff", 15, 190);
Person p7("gg", 16, 190);
l1.push_back(p1);
l1.push_back(p2);
l1.push_back(p3);
l1.push_back(p4);
l1.push_back(p5);
l1.push_back(p6);
l1.push_back(p7);
for (list<Person>::const_iterator it = l1.begin(); it != l1.end(); it++){
cout << "name: "<<(*it).name << " "<<"age: "<<(*it).age
<<" height: "<<(*it).height<<endl;
}
cout << "-----------------------------------------------" << endl;
l1.sort(ComparePerson);
//令其在年龄相同的情况下按身高降序
for (list<Person>::const_iterator it = l1.begin(); it != l1.end(); it++){
cout << "name: " << (*it).name << " " << "age: " << (*it).age
<< " height: " << (*it).height << endl;
}
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
四、SET容器
1.set容器基本概念
简介: 所有元素都会在插入时自动被排序
本质: set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset区别:
- set不可以插入重复数据,而multiset可以
- set插入数据的同时会返回插入结果,表示插入是否成功
- multiset不会检测数据,因此可以插入重复数据
2.set容器构造函数和赋值操作
函数原型:
构造:
-
set<T> st;
默认构造函数。 -
set(const set &st);
拷贝构造函数。
赋值。
set& operator=(const set &st);
重载等号操作符。
#include<iostream>
#include<set>
using namespace std;
void print(set<int>s){
for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
cout << (*it) << " ";
cout << endl;
}
void test(){
set<int> s;
s.insert(10);
s.insert(10);//不允许同元素存在
s.insert(40);//自动排序
s.insert(20);
s.insert(30);
print(s);
set<int> s2(s);
print(s2);
set<int>s3;
s3 = s2;
print(s3);
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
3.set容器大小和交换操作
函数原型:
-
size();
返回容器中元素的数目。 -
empty();
判断容器是否为空。 -
swap(st);
交换两个集合容器。
#include<iostream>
#include<set>
using namespace std;
void print(set<int>s){
for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
cout << (*it) << " ";
cout << endl;
}
void test(){
set<int> s;
if (s.empty()) cout << "empty" << endl;
else {
cout << "not empty" << endl;
cout << "size: " << s.size() << endl;
}
s.insert(10);
s.insert(10);
s.insert(40);
s.insert(20);
s.insert(30);
print(s);
if (s.empty()) cout << "empty" << endl;
else {
cout << "not empty" << endl;
cout << "size: " << s.size() << endl;
}
set<int> s2;
s2.insert(100);
s2.insert(200);
s2.insert(400);
s2.insert(300);
cout << "preview: s"<<endl;
print(s);
cout << "s2" << endl;
print(s2);
s.swap(s2);
cout << "next: s" << endl;
print(s);
cout << "s2" << endl;
print(s2);
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
4.set容器插入和删除
函数原型:
-
insert(elem);
在容器中插入元素。 -
clear();
清除所有元素。 -
erase(pos);
删除pos迭代器所指的元素,返回下一个元素的迭代器。 -
erase(beg, end);
删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。 -
erase(elem);
删除容器中值为elem的元素。
#include<iostream>
#include<set>
using namespace std;
void print(set<int>s){
for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
cout << (*it) << " ";
cout << endl;
}
void test(){
set<int> s;
s.insert(20);
s.insert(10);
s.insert(40);
s.insert(20);
s.insert(30);
print(s);
s.erase(s.begin());
print(s);
s.erase(30);
print(s);
s.erase(s.begin(), s.end());//s.clear()
print(s);
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
5.set容器查找和统计
函数原型:
-
find(key);
查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end()。 -
count(key);
统计key的元素个数。
#include<iostream>
#include<set>
using namespace std;
void print(set<int>s){
for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
cout << (*it) << " ";
cout << endl;
}
void test(){
set<int> s;
s.insert(20);
s.insert(10);
s.insert(40);
s.insert(20);
s.insert(30);
print(s);
set<int>::iterator it = s.find(20);
if (it != s.end()) cout << "找到: " << *it << endl;
else cout << "没找到" << endl;
it = s.find(2);
if (it != s.end()) cout << "找到了" << *it << endl;
else cout << "没找到" << endl;
int num = s.count(20);
cout << "num: " << num << endl;
num = s.count(2);
cout << "num: " << num << endl;
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
6.set容器和multiset容器区别
#include<iostream>
#include<set>
using namespace std;
void test(){
set<int> s;
pair<set<int>::iterator, bool>ret =s.insert(10);
if (ret.second) cout << "第一次查入成功" << endl;
else cout << "第二次插入失败" << endl;
ret =s.insert(10);
if (ret.second) cout << "第一次查入成功" << endl;
else cout << "第二次插入失败" << endl;
multiset<int> m;
m.insert(10);
m.insert(10);
m.insert(10);
for (multiset<int>::iterator it = m.begin(); it != m.end(); it++) cout << *it << " ";
cout << endl;
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
7.pair队组创建
创建方式:
-
pair<type, type> p ( value1, value2 );
-
pair<type, type> p = make_pair( value1, value2 );
#include<iostream>
#include<string>
using namespace std;
void test(){
pair<string, int>p("aa", 18);
cout << "name: " << p.first << " age: " << p.second << endl;
pair<string, int>p1=make_pair("bb",19);
cout << "name: " << p1.first << " age: " << p1.second << endl;
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
8.set容器内置类型指定排序
#include<iostream>
#include<set>
using namespace std;
class Compare{
public:
bool operator()(int v1, int v2){
return v1 > v2;
}
};
void test(){
set<int, Compare>s;
s.insert(10);
s.insert(30);
s.insert(20);
s.insert(50);
s.insert(40);
for (set<int, Compare>::iterator it = s.begin(); it != s.end(); it++) cout << *it << " ";
cout << endl;
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
9.set容器自定义数据类型指定排序
#include<iostream>
#include<set>
#include<string>
using namespace std;
class Person{
public:
int age;
string name;
Person(string name, int age){
this->age = age;
this->name = name;
}
};
class Compare{
public:
bool operator()(const Person &p1, const Person &p2){
return p1.age>p2.age;
}
};//仿函数
void test(){
set<Person, Compare>s;
Person p1("aa", 10);
Person p2("bb", 10);
Person p3("cc", 10);
//有一成员数据相同,set容器将只保留第一个
Person p4("dd", 12);
Person p5("ee", 12);
Person p6("ff", 15);
Person p7("gg", 16);
s.insert(p1);
s.insert(p2);
s.insert(p3);
s.insert(p4);
s.insert(p5);
s.insert(p6);
s.insert(p7);
for (set<Person, Compare>::iterator it = s.begin(); it != s.end(); it++) cout << "name: " << (*it).name << " age:" << (*it).age << endl;
cout << endl;
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
五、MAP容器
1.map容器基本概念
简介:
- map中所有元素都是pair
- pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
- 所有元素都会根据元素的键值自动排序
本质: map/multimap属于关联式容器,底层结构是用二叉树实现。
优点: 可以根据key值快速找到value值
map和multimap区别:
- map不允许容器中有重复key值元素
- multimap允许容器中有重复key值元素
2.map容器构造函数和赋值操作
函数原型:
构造:
-
map<T1, T2> mp;
map默认构造函数。 -
map(const map &mp);
拷贝构造函数。
赋值:
map& operator=(const map &mp);
重载等号操作符。
#include<iostream>
#include<map>
using namespace std;
void print(map<int, int>&m){
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
cout << "key: " << (*it).first << " value: " << it->second << endl;
cout << endl;
}
void test(){
map<int, int>m;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(4, 40));
m.insert(pair<int, int>(2, 20));
print(m);
map<int, int>m2(m);
print(m);
map<int, int>m3;
m3 = m2;
print(m3);
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
3.map容器大小和交换操作
函数原型:
size();
返回容器中元素的数目。empty();
判断容器是否为空。swap(st);
交换两个集合容器。
#include<iostream>
#include<map>
using namespace std;
void print(map<int, int>&m){
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
cout << "key: " << (*it).first << " value: " << it->second << endl;
cout << endl;
}
void test(){
map<int, int>m;
if (m.empty()) cout << "empty" << endl;
else cout << "Not empty " << "size: " << m.size() << endl;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(4, 40));
m.insert(pair<int, int>(2, 20));
if (m.empty()) cout << "empty" << endl;
else cout << "Not empty " << "size: " << m.size() << endl;
map<int, int>m2;
m2.insert(pair<int, int>(1, 10));
m2.insert(pair<int, int>(4, 40));
m2.insert(pair<int, int>(2, 20));
cout << "交换前" << endl;
print(m);
print(m2);
m.swap(m2);
cout << "交换后" << endl;
print(m);
print(m2);
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
4.map容器插入和删除
函数原型:
-
insert(elem);
在容器中插入元素。 -
clear();
清除所有元素。 -
erase(pos);
删除pos迭代器所指的元素,返回下一个元素的迭代器。 -
erase(beg, end);
删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。 -
erase(key);
删除容器中值为key的元素。
#include<iostream>
#include<map>
using namespace std;
void print(map<int, int>&m){
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
cout << "key: " << (*it).first << " value: " << it->second << endl;
cout << endl;
}
void test(){
map<int, int>m;
m.insert(pair<int, int>(1, 10));
m.insert(make_pair(3, 30));
m.insert(map<int, int>::value_type(2, 20));
m[4] = 40;
/*cout << m[5];*/
//虽然没有输入数据,但照样能打印出来,数值为0
print(m);
m.erase(m.begin());
m.erase(3);
print(m);
m.erase(m.begin(), m.end());//m.clear();
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
5.map容器查找和统计
函数原型:
-
find(key);
查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end()。 -
count(key);
统计key的元素个数。
#include<iostream>
#include<map>
using namespace std;
void test(){
map<int, int>m;
m.insert(pair<int, int>(1, 10));
m.insert(make_pair(3, 30));
m.insert(map<int, int>::value_type(2, 20));
m[4] = 40;
map<int, int>::iterator it = m.find(2);
if (it != m.end()) cout << "key: " << (*it).first << " value: " << (*it).second << endl;
else cout << "没找到" << endl;
it = m.find(5);
if (it != m.end()) cout << "key: " << (*it).first << " value: " << it->second << endl;
else cout << "没找到" << endl;
int num = m.count(3);
cout << "num: " << num << endl;
}
int main(){
test();
system("pause");
return 0;
}
运行效果:
6.map容器排序
#include<iostream>
#include<map>
using namespace std;
class Compare{
public:
bool operator()(int val1, int val2){
return val1 > val2;
}
};
void test(){
map<int, int, Compare>m;
m.insert(pair<int, int>(1, 10));
m.insert(make_pair(3, 30));
m.insert(map<int, int>::value_type(2, 20));
m[4] = 40;
for (map<int, int, Compare>::iterator it = m.begin(); it != m.end();it++)
cout << "key: " << (*it).first << " value: " << it->second << endl;
cout << endl;
}
int main(){
test();
system("pause");
return 0;
}
运行效果: