C++ 常见容器使用汇总

set容器使用

set 基本概念

集合 有序(自动排序,默认从小到大) 元素唯一
例:

#include <iostream>
#include <set>

using namespace std;

set<int> set1;       // 从小到大排列
set<int, less<int>> set2;    // 从小到大排列       
set<int, greater<int>> set3;   // 从大到小排列

set容器的插入和遍历操作

set<int> set1;                  // 从小到大排列
for(int i = 0; i<5; i++)
{
    int tmp = rand();
    set1.insert(tmp);
}
set1.insert(100);
set1.insert(100);
set1.insert(100);

for(set<int>::iterator it =set1.begin(); it !=set1.end(); it++)
{
     cout << *it << " ";
}            //  输出  1 3 100 4566 7889 88899

set 容器的删除操作

while (!set1.empty())     //  遍历删除所有元素
{
     set<int>::iterator it = set1.begin();
     set1.erase(set1.begin());      // 删除首元素
}

set<int, greater<int>> set1;                  // 从大到小排列
for(int i = 0; i<5; i++)
{
    int tmp = rand();
    set1.insert(tmp);
}
set1.insert(100);
set1.insert(100);
set1.insert(100);

for(set<int>::iterator it =set1.begin(); it !=set1.end(); it++)
{
     cout << *it << " ";
}            //  输出   88899   8888 777 555 100 13 

set容器在class,自定义类型排序

struct funstudent                    //  仿函数
{
    bool operator()(const student &left,  const student &right)
    {
        if(left.age < right.age)
	   {
           return true;
	   }
	   else
	   {
           return false;
	   }
    }	
}
void main()
{
     student s1("s1", 31);
     student s1("s2", 22);
     student s1("s3", 44);
     student s1("s4", 11);

     set<student,  funstudent>  set1;       //  必须借用仿函数实现
     set1.insert(s1);
     set1.insert(s2);
     set1.insert(s3);
     set1.insert(s4);

     //遍历
    for(set<student,  funstudent>::iterator it = set1.begin(), it != set1.end(), it++)
	{
         cout  << it->age <<endl;                       
	}   //     输出 11 22 31 44
}

使用pair 来判断插入的结果

// 注:相同的元素插入会失败

set<student,  funstudent>  set1; 
pair<set<student,  funstudent>::iterator, bool> pair1 = set1.insert(s1);
if(pair.second == true)
{
     cout << "插入s1成功" <<endl;
}
else
{
     cout << "插入s1失败" <<endl;
}

set容器的find查找操作

set<int> set1;
for(int i = 0; i<10; i++)
{
      set1.insert(i+1);
}
for(set<int>::iterator it = set1.begin(); it!=set1.end(); it++)
{
     cout << *it <<endl ;      //1 2 3 4 5 6 7 8 9 10
}

set<int>iterator it0 =set1.find(5);
cout << *it0 <<endl;        // 5

int num =set1.count(5);
cout<< num <<endl;       // 1

// 把元素5删除掉
set1.erase(5);

pair<set<int>::iterator, set<int>::iterator> pair1 = set1.equal_range(5);
set<int>::iterator it3 =pair1.first;      输出大于等于5的元素
cout << *it3 <<endl;        // 5      // 如果擦除5 ,则输出6  
set<int>::iterator it4 =pair1.second;  输出大于5 的元素
cout << *it4 <<endl;        // 6      //如果擦除5 ,则输出6    

vector容器使用

vector容器常见使用场景

#include <vector>

using namespace std;

vector<int> v1;
cout << "length" << v1.size() <<endl;       // 0
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
cout << "length" << v1.size() <<endl;       // 3
// 1 3 5
v1.front()    // 获取头部元素 1           v1.front() = 1;     //修改头部元素
v1.back()  //获取尾部元素                  v1.back() = 5;     //修改尾部元素
while(v1.size() > 0)          // 遍历并删除所有元素
{
	v1.pop_back();    // 删除尾部元素		
}

vector 的初始化方式

//方式一
vector<int> v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
//方式二
vector<int> v2 = v1;
//方式三
vector<int> v3(3, 9);   // 存放3个元素,每个元素的值是9

vector 的遍历

vector<int> v1(10);      //提前把内存准备好
for(int i=0; i<10; i++)
{
      v1[i] = i + 1;
}

for(int i = 0; i < 10; i++)
{
    printf("%d ", v1[i]);
}

vector<int> teData; //不提前准备内存
teData.push_back(1);
teData.push_back(2);
for (int i = 0; i < teData.size(); i++)
{
    cout << teData[i] << " ";
}
cout << std::endl;  // 1 2

//push_back 的强化记忆
vector<int> v1(2);  //占用index 1,2
v1.push_back(100);  //从index 2开始插入
v1.push_back(200);  //从index 3开始插入
//输出   0 0 100 200             大小为 4

用迭代器遍历容器 vector

vector<int>::const_iterator                
vector<int>::const_reverse_iterator

vector<int> v1(10);      //提前把内存准备好
for(int i=0; i<10; i++)
{
      v1[i] = i + 1;
}
//正向遍历
for(vector<int>::iterator it = v1.begin(); it!=v1.end(); it++)
{
     cout << *it << " ";       // 1 2 3 4 5 6 7 8 9 10
}
//逆序遍历
for(vector<int>::reverse_iterator rit = v1.rbegin(); rit!=v1.rend(); rit++)
{
     count << *rit << " ";            // 10 9 8 7 6 5 4 3 2 1
}

vector的删除

vector<int> v1(10);      
for(int i=0; i<10; i++)
{
     v1[i] = i + 1;
}
//区间删除
v1.erase(v1.begin(), v1.begin()+3);        //输出 4 5 6 7 8 9 10

//根据元素的位置,指定位置删除
v1.erase(v1.begin()); //删除第一个元素 , 在前面的基础上输出 5 6 7 8 9 10
//v1.erase(v1.begin() + 1);  //删除第二个元素,总大小继续减1

//删除指定元素
std::remove(v1.begin(), v1.end(), 3); //将容器中为3的元素全部删除,但容器总容量不变

// 删除最后一个元素
vector<int> v2{ 1,2,3,4,5 };
v2.pop_back();   //删除最后一个元素,但总容量不变
for(int i=0; i<v2.size(); i++)
{
	cout << v2[i] << endl;
}
//输出: 1 2 3 4

//根据元素的值删除
v1[1] = 2;
v1[3] = 2;            // 5 2 7 2 9 10
for(vector<int>::iterator it = v1.begin(); it!=v1.end(); )
{
     if(*it == 2)
     {
         it = v1.erase(it); 
//当删除迭代器所指向的元素的时候,erase删除元素会让it自动向下移动,所以it++写在下面  
     }
     else
     {
         it++;
     }
}    //    输出 5 7 9 10

vector的插入与清空

vector<int> v1;
v1.insert(v1.begin(), 100);
printf("data=%d\n", v1.front()); //100

printf("%d\n", v1.size());  //1
v1.clear();
printf("%d\n", v1.size());  // 0

queue容器使用

队列中基本数据类型

#include <iostream>
#include <queue>

queue<int> q;
q.push(1);
q.push(2);
q.push(3);

cout << "队头元素" <<q.front() <<endl;   //1
cout << "队列的大小" << q.size() <<endl;  //3
while( !q.empty())
{
    int tmp = q.front();
    cout << tmp << " ";                     
    //或者     
    //cout << q.front() <<endl;
    //q.pop(); 
                       
}  // 输出 1 2 3

队列的算法和容器的分离

teacher t1, t2, t3;
t1.age = 31;
t2.age = 32;
t3.age = 33;
//普通常量存储
queue<teacher> s;
s.push(t1);
s.push(t2);    
s.push(t3);   
 
while( !s.empty())
{
    teacher tmp = s.front();
    cout << age <<endl;
	s.pop();
}           
teacher t1, t2, t3;
t1.age = 31;
t2.age = 32;
t3.age = 33;
//指针类型存储
queue<teacher *> s;
s.push(&t1);
s.push(&t2);    
s.push(&t3);    

while( !s.empty())
{
     teacher *p = s.front();
     cout << p->age <<endl;
     s.pop();
}         

map容器使用

#include <iostream>
#include <map>

//map<key, value>  key 是唯一的,而且只能对应一个 value
map<int, string> map1;

map容器的插入操作

//方法1
map1.insert(pair<int, string>(1, "teacher01"));

//方法2
map1.insert(make_pair(3, "teahcer01"));

//方法3
map1.insert(map<int, string>::value_type(5, "teacher01"));

//方法4
map1[7] = "teacher07";

map容器的遍历操作

for(map<int, string>::iterator it =map1.begin(); it !=map1.end(); it++)
{
    cout << it->first << "\t" << it->second <<endl;
}

map容器的删除操作

while(!map1.empty())
{
    map<int, string>::iterator it = map1.begin();     
    map1.erase(it);
}

判断是否插入成功

(1)方式一

3种方法插入都是用这种方式判断:
pair<map<int, string>::iterator, bool> mypair = map1.insert(pair<int, string>(1, "teacher01");
if(mypair.second == true)
{
    cout<< "key 插入成功" <<endl;
}

(2)方式二

map1[7] = "teacher07";
map1[7] = "teacher77";       // 不会插入失败,   只会覆盖,输出  teacher77

map的查找操作:

map<int, string>::iterator it2 = map1.find(100);
if(it2 == map1.end())
{
    cout << "key 100 的值 不存在" <<endl;
}
else
{
    cout <<it2->first << "\t" << it2->second <<endl;
}

// equal_range 
pair<map<int, string>::iterator, map<int, string>::iterator> mypair = map1.equal_range(5);
// 第一个迭代器  >=5 的位置
//第二个迭代器 >5 的位置
if( mypair.first == map1.end())
{
    cout << ">=5的位置不存在" <<endl;
}
else
{
    cout << mypair.first->first <<"\t" <<mypair.first->second <<endl;
}

if( mypair.second == map1.end())
{
    cout << ">=5的位置不存在" <<endl;
}
else
{
    cout << mypair.second->first <<"\t" <<mypair.second->second <<endl;
}    

stack容器用法

栈模型

#include <iostream>
#include <stack>

using namespace std;

stack<int> s;

入栈

for(int i =0; i<10; i++)
{
    s.push(i+1);
}
cout << "栈的大小" << s.size() <<endl;

出栈

while( !s.empty())
{
    int tmp = s.top();  //获取栈元素
    cout << tmp << " ";
    s.pop();      // 弹出栈顶元素
}   // 输出 10 9 8 7 6 5 4 3 2 1         

用法一

teacher t1, t2, t3;
t1.age = 31;
t2.age = 32;
t3.age = 33;

stack<teacher> s;
s.push(t1);
s.push(t2);    
s.push(t3);    
while( !s.empty())
{
    teacher tmp = s.top();
    cout << age <<endl;
    s.pop();
}             

用法二

teacher t1, t2, t3;
t1.age = 31;
t2.age = 32;
t3.age = 33;

stack<teacher *> s;
s.push(&t1);
s.push(&t2);    
s.push(&t3);    
while( !s.empty())
{
	teacher *p = s.top();
	cout << p->age <<endl;
	s.pop();
}                      

list (双向链表)容器使用

list的初始化操作

#include <iostream>
#include <list>

list<int> l;
cout << "list的大小" <<l.size() <<endl;          // 0
for(int i = 0; i<10; i++)
{
	l.push_back(i);   //从尾部插入元素,尾插法
}
cout << "list的大小"  <<l.size() <<endl;

list<int>::iterator it = l.begin();
while ( it != l.end())
{
	cout << *it << " ";
	it++;
}
//输出  0   1    2    3     4    5

// list不能随机访问
it = l.begin();
it++;
it++;
it++;
it = it +5;         // 错误,不支持随机访问

list的插入操作

l.insert(it, 100);           
for(list<list>::iterator it = l.begin(); it!=l.end(); i++)
{
	cout << *it << " ";         // 输出  0  1 2 100 3 4 5
}
// 结论: 链表的节点index 序号是从0号位置开始

list 的删除操作

  //  0  1  2  3  4  5
list<int>::iterator it1 = l.begin();
list<int>::iterator it2 = l.begin();
it2++;
it2++;
it2++;

l.erase(it1, it2);  // 删除操作的区间为 左闭右开
for(list<list>::iterator it = l.begin(); it!=l.end(); i++)
{
	cout << *it << " ";  // 输出  3  4  5    
}

//删除第一个元素      0  1  2  3  4  5        
l.erase(l.begin());        //输出: 1 2 3 4 5

//删除元素1           0 1 1 1 2 3
l.remove(1)   //输出: 0 2 3	

容器在类中的值拷贝

简介

容器类值的插入是属于拷贝, 所以要使用 拷贝构造函数和 =运算符重载。

使用举例

class teacher
{
public:
	teacher(char * name, int age)
	{
	       m_pname = new char[strlen(name) +1];
	       strcpy(m_pname, name);
	       m_age = age;
	}
	~teacher
	{
	      delete[] m_pname;
	      m_pname = NULL;
	      m_age = 0;
	}
private:
	char  *m_pname;
	int    m_age;
};

void main()
{
	teacher t1("t1", 31);
	vector<teacher> v1;
	v1.push_back(t1);       // 如果不重写拷贝构造函数和赋值运算符重载,则会因为内存无法拷贝出错

}

解决:
//  拷贝构造函数
teacher(const teacher &obj)
{
	m_pname = new char[strlen(obj.m_pname) + 1];
	strcpy(m_pname, obj.m_pname);
	m_age = obj.m_age;
}

//  赋值运算符重载
teacher operator=(const teacher &obj)
{
//  1)  把旧的内存释放掉
	if(m_pname != NULL)
	{
	       delete[] m_pname;
	       m_pname = NULL;
	       m_age = 0;
	}
//  2)    分配内存
    m_pname = new char[strlen(obj.m_pname) + 1];
//  3)     拷贝数据
    strcpy(m_pname, obj.m_pname);
    m_age = obj.m_age;
	
	return *this;
}

deque容器(双端数组)使用

deque的初始化操作

#include <iostream>
#include <deque>

using namespace std;

deque<int> d1;
d1.push_back(1);
d1.push_back(3);
d1.push_back(5);

d1.push_front(-11);
d1.push_front(-33);
d1.push_front(-55);            //  -55  -33 -11 1 3 5

cout << "头部元素" << d1.front() <<endl;    // -55
cout << "尾部元素" << d1.back() <<endl;  //       5

//删除元素
d1.pop_front();
d1.pop_back();         // -33 -11 1 3

deque的查找操作

deque<int>::iterator it = find(d1.begin(), d1.end(), -33);
if( it != d1.end())
{
    cout << "-33数组的下标是" << distance(d1.begin(), it) <<endl;        // d1.begin()为偏移量
}
else
{
	cout << "没有找到值为-33的元素" << endl;
}

优先级队列

容器 priority_queue优先级队列分为 最大优先级队列和最小优先级队列

头文件

  #include "queue"

初始化

priority_queue<int> p1;      // 默认情况是 最大优先级队列
priority_queue<int, vector<int>, less<int>> p2;          //手动设置最大优先级队列
priority_queue<int, vector<int>, greater<int>> p3;    //手动设置最小优先级队列

最大优先级队列的初始化和遍历

p1.push(33);
p1.push(11);
p1.push(55);
p1.push(22);

cout <<  "队头元素" << p1.top() <<endl;
cout << "队列的大小" << p1.size() <<endl;

while(p1.size() > 0)
{
    cout << p1.top() << " ";
    p1.top();
}          
// 输出 55 33 22 11

最小优先级队列的初始化和遍历

p3.push(33);
p3.push(11);
p3.push(55);
p3.push(22);

cout <<  "队头元素" << p3.top() <<endl;
cout << "队列的大小" << p3.size() <<endl;

while(p1.size() > 0)
{
    cout << p3.top() << " ";
    p3.top();
}        
// 输出 11 22 33 55

迭代器:

//迭代器相当于指针,可以遍历出容器中的元素
for(vector<int>::iterator it = v1.begin; it!=v1.end; it++)      
{
	cout<< *it <<endl;
}
teacher t1,t2,t3;
vector<teacher > v1 
v1.push_back(t1);
v1.push_back(t2);
v1.push_back(t3); 
//迭代器相当于指针,可以遍历出容器中的元素
for(vector<int>::iterator it = v1.begin(); it!=v1.end(); it++)      
{
	cout<< (*it).age <<endl;
}

总结

各大容器的特点:

类型vectordequelistsetmultisetmapmultimap
内存结构单端数组双端数组双向链表二叉树二叉树二叉树二叉树
是否可随机存储对key而言是
元素搜寻速度非常慢对key而言快对key而言快
快速安插移除尾端头尾两端任何位置- --------
  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路过的小熊~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值