STL容器基础 -1

stack容器

stack栈 是一种后进先出的数据结构,它只有一个出口,进栈和出栈的一端叫栈顶,

#include<stack>
void test()
{
   stack<int> s;
   s.push(10);
   s.push(20);
   s.push(30);

   stack<int>s1(s); // 拷贝构造
  cout << "获取栈顶元素: "  << s1.top() << endl;

  while(s.empty())
{
    cout << "栈的大小: " << s.size();
}
}

queue队列

队列是一种先进先出的数据结构,出队的一段叫队头, 入队的一段叫队尾,队列中只有队尾和队头才可以被外界使用,

#include<queue>
void test()
{
    queue<int> p;
    p.push(10);
    p.push(20);  // 入队
    
   p.pop(); // 出队

  cout << "队头元素: " << p.front() << endl;
  cout << "队尾元素: " << p.back() << endl;

  while(p.empty())
{
   cout << "队列的大小为: " << p.size() << endl;
}
}

list容器

list(链表) -- 将链表进行链式存储,链表是由结点组成的 每一个结点存储着 数据域 和一个指针域,STL中的链表是一个双向循环链表

list的优点:采用动态存储,不会造成空间的浪费;插入删除元素方便,不需要移动大量数据元素

list的缺点:链表灵活,但是遍历整个链表的时间复杂度和空间复杂度高,

#include<list>
void test()
{
   list<int> l;
  l.push_back(10);
  l.push_back(29);
  
  list<int>l1;
  l1 = 1;  //赋值
  
  list<int>l2(l1); //拷贝赋值
  
 list<int>l3;
 l3.assign(l1.begin(),l1.end());

 list<int> l4(10,100); // 构造
 list<int> l5;
 l5.assign(10,99); // 赋值

  l5.swap(l4); // 两个list容器交换


}

list大小操作

#include<list>
void test()
{
   list<int> l;
 l.push_front(10);
 l.push_front(20);

 while(l.empty())
{
   cout << "l的大小为: " << l.size() << endl;
}

 l.resize(1); //重新制定大小 为1 
}

empty() 判空; resize()重新指定大小, size()元素个数

list的插入和删除

#include<list>
void test()
{
   list<int> l;
   l.push_back(10); // 尾插尾删
   l.pop_back();

   l.push_front(20); // 头插头删
   l.pop_front(); 

  //插入
  l.insert(l.begin(),10); 
  l.insert(l.begin(), 2, 100);
  l.insert(l.begin(),l.begin(),l.end());

 // 删除
 l.erase(l.end());
 l.erase(l.begin(),l.end()); // 删除区间所有元素
 
// 清空容器
  l.clear(); 

 // remove 移除指定元素
 l.remove(10);
}

push_back; push_front; pop_back(); pop_front; insert(); erase(); clear();  remove:移除指定元素,不需要用到容器

list数据存取:list(链表)不支持随机访问,因为采用的不是连续的存储空间, 用front() 和 back() 来获取头和尾的元素, 不能用 [ ] 和 at 来访问链表中的元素,因为存储空间不是连续的

#include<list>
void test()
{
   list<int> l;
   l.push_back(20);
   l.push_front(30);
   
cout << "链头为 : " << l.front() << endl;
cout << "链尾为: " << l.back() << endl;

//不能用[ ] 和 at 来访问链表数据, 因为链表不是采用的连续的存储空间来存储,不支持随机访问
}

list反转和排序

reverse()反转 ; sort () 排序;

sort作为全局函数来用只能对支持随机访问的容器进行访问,对list而言,内部由sort成员函数来实现排序

#include<list>
list<int> l1;
list<int> l2;
l1.reverse(l2);

l2.sort(); //默认是升序排序,如果要制定排序类型利用仿函数

class compare
{
public: 
      bool operator() (int val ,int val1)
{
   return val > va11 ;
}
};

l1.sort(compare);//仿函数制定函数类型

set/multiset容器

所有元素都会在插入时自动被排序, 本质上:set/multiset属于关联式容器,底层结构是二叉树

set与multiset容器的区别: set不允许容器中有重复的元素,multiset容器中有重复的元素

#include<set>
set<int> s;
s.insert(10);
s.insert(20);
s.insert(2);  //用insert插入,在set容器中 插入时会自动进行排序


set<int> s1(s); // 拷贝
set<int> s2;
s2 = s1 ; // 赋值

set的大小和交换:

empty()判空, size()元素个数;  swap(t)交换两个容器

#include<set>
set<int> s;
s.insert(1);
s.insert(22);

set<int> s1;
s1.insert(33);

while(s1.empty())
{
   cout  << "s1的大小为: " << s1.size() << endl;
}

s1.swap(s); // 交换两个容器

set的插入和删除:

insert( 值) 插入; erase(删除); clear()清空

#include<set>
set<int>s;
s.insert(1);
s.insert(14);
s.insert(10);

s.erase(10) ; //删除指定值;
s.erase(s.begin()); // 删除迭代器的元素
s.erase(s.begin(),s.end()) ; //删除区间

s.clear(); //清空容器

  set查找和统计:

find(key);查找key是否存在,若存在,返回该键的元素的迭代器,若不存在,返回set.end(); count(key)统计key的个数

#include<set>
set<int> s;
s.insert(10);
s.insert(10);
s.insert(5);

//find查找返回一个迭代器, 若没有存在,则返回end()
set<int> :: iterator pos = s.find(10); 
if(pos != s.end())
{
  cout << *pos << endl;
}

int num = s.count(10); // 统计10的个数存放在num中

set不可以插入重复数据,而multiset可以,set插入数据是会返回插入结果,表示插入是否成功

multiset不会检测数据,因此可以重复插入数据

pair对组的创建

pair<type,type > p (value1, value2);   pair<type,type> p = make_pair(value1, value2);

first访问对组中的第一个数据,second 表示访问数组中的第二个数据

#include<string>
pair<string ,int > p ("张三", 10);

pair<string,int> p1 = make_pair("王五",29);

cout << p.first << "  " << p.second << endl;

set内置数据类型排序:

利用仿函数来改变排序规则

operator()重载运算符(),类型根据容器的类型设定

#include<set>
class mycompare
{
 public: 
  bool operator()(int val1, int val2)  const // 要加const修饰不然会报错
{
    return val1 > val2 ; // 降序排列
}
};

set<int,mycompare> s ;

set自定义数据类型排序:

对于自定义数据类型,必须指定排序规则才可以插入数据,因为编译器不知道该如何对自定义数据类型进行排序

#include<set>
class mycompare
{
public:
   bool operator()(const Person &p1, const Person & p2) const
{
           return p1.age > p2.age ; // 年龄降序排列
}
};

set<Person,mycompare> s;
s.insert(p);
s,insert(p1);

map/multimap容器

map中的所有元素都是pair , pair中的第一个元素表为key(键值)起到索引作用,第二个元素为value(实值);所有元素都会根据元素的键值进行排序

本质上:map/multimap是属于关联式容器,底层结构是用二叉树实现

优点:可以根据key值来快速找到元素

#include<map>
map<int,int> m; //map中所有的元素都是对组
m.insert(pair<int,int>(1,22));
m.insert(pair<int,int>(3,11)); // 第一个元素表示为键值, 第二个元素为实值, 会根据键值自动排序

map<int,int> m1;
m1 = m;  //赋值
 
map<int,int> m2(m1);  // 拷贝构造

map中的数据都是成对存在的,插入数据时要用到对组

map的大小和交换:size()返回容器中的元素,empty()判空,swap(s) 交换两个容器

#include<map>
map<int,int> m;
m.insert(pair<int,int>(1,22));
m.insert(pair<int,int>(3,44));
if(m.empty())
{
  cout << "m的大小为: " << m.size() << endl;
}

map<int,int> m1;
m1.swap(m); // 交换两个容器

map容器的插入和删除:

insert( elem) 在容器中插入元素; clear()清空所有元素;erase()删除元素;

#include<map>
map<int,int> m;
m.insert(pair<int,int>(1,44));
m.insert(pair<int,int>(3,22));

m.insert(make_pair(2,23)); //这种插入方式最实用

m.erase(1); //删除键值为1 的元素
m.erase(m.begin(),m.end()); // 删除区间的元素
m.erase(m.begin()); //删除迭代器的开始元素

m.clear(); //清空容器

map的查找和统计:

find()查找key值是否存在,若存在,返回该元素的迭代器,若不存在,返回set.end()

count(key);统计 key的个数

#include<map>
map<int,int> m;
m.insert(make_pair(1,22));
m.insert(make_pair(2,11));
m.insert(make_pair(3,33));

map<int,int> :: iterator pos = m.find(2);  //查找键值为2的数返回一个迭代器,没有返回end()

if(pos!= m.end())
{
   cout << pos->first << "  "   << pos->second << endl;
}

在map中count的统计要么为1 要么为0,因为map不能重复插入数据

map排序:利用仿函数改变排序规则

#include<map>
class mycompare
{
 public:
 bool operator() (int val1,int val2)
{
   return val1 > val2 ; //降序排列
}
};

map<int,int,mycompare> m;
m.insert(make_pair(1,44));
m.insert(make_pair(3,22));

对于自定义数据类型,map必须要指定排序规则,同set容器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值