C++STL中的常用的数据结构

发布时间 2023-06-01 15:48:59作者: 阿风小子

STL中常用的数据结构:

[1]  stack、queue默认的底层实现为deque结构。

[2]  deque:用map管理多个size大小的连续内存块,方便头尾插入。

[3]  vector:变长动态数组,每次增大1.5倍,删除元素时不释放空间。

[4]  priority_queue底层默认采用vector向量O(nlogn)。

[5]  list:双向链表容器。

[6]  slist:单向链表容器。

[7]  bit_vector:一个bit位元素的序列容器,常用于硬件端口的控制。区别于vector<bool>重要特性是节省空间。

[8]  set集合容器、multiset多重集合容器均采用红黑树实现,后者允许相同元素。

[9]  map、multimap为映照容器,底层为红黑树。后者允许相同元素。

[10] hash_set哈希集合容器/hash_map哈希映照容器均采用hashtable。

[11] string基本字符序列容器。

1、C++ vector使用方法
1.1 基本操作
(1)头文件#include<vector>
(2)创建vector对象,vector<int> vec;
(3)尾部插入数字:vec.push_back(a);
(4)使用下标访问元素,cout<<vec[0]<<endl;记住下标是从0开始的。
(5)使用迭代器访问元素.

vector<int>::iterator it;
for(it=vec.begin();it!=vec.end();it++)
    cout<<*it<<endl;
  •  

(6)插入元素:vec.insert(vec.begin()+i,a);在第i+1个元素前面插入a;
(7)删除元素:vec.erase(vec.begin()+2);删除第3个元素
vec.erase(vec.begin()+i,vec.end()+j);删除区间[i,j-1];区间从0开始
(8)向量大小:vec.size();
(9)清空:vec.clear();
特别提示:这里有begin()end()函数、front()back()的差别
1.2重要说明
vector的元素不仅仅可以是int,double,string,还可以是结构体,但是要注意:结构体要定义为全局的,否则会出错。
1.3算法
(1) 使用reverse将元素翻转:需要头文件

#include<algorithm>
reverse(vec.begin(),vec.end());

将元素翻转,即逆序排列!

(在vector中,如果一个函数中需要两个迭代器,一般后一个都不包含)
(2)使用sort排序:需要头文件

#include<algorithm>,
sort(vec.begin(),vec.end());

 

(默认是按升序排列,即从小到大).
可以通过重写排序比较函数按照降序比较,如下:
定义排序比较函数:

bool Comp(const int &a,const int &b)
{
    return a>b;
}

调用时:sort(vec.begin(),vec.end(),Comp),这样就降序排序。

输出Vector的中的元素

vector<float> vecClass; 

int nSize = vecClass.size();  
//打印vecClass,方法一:  
for(int i=0;i<nSize;i++)    
{    
   cout<<vecClass[i]<<"     ";    
}    
   cout<<endl;   

需要注意的是:以方法一进行输出时,数组的下表必须保证是整数。

 //打印vecClass,方法二:     
for(int i=0;i<nSize;i++)    
{    
   cout<<vecClass.at(i)<<"     ";    
}    
   cout<<endl;    
  •  
//打印vecClass,方法三:输出某一指定的数值时不方便
for(vector<float>::iterator it = vecClass.begin();it!=vecClass.end();it++)    
{    
    cout<<*it<<"   ";    
}    
    cout<<endl;    

2.list的用法
void push_front(const T & val) 将 val 插入链表最前面
void pop_front() 删除链表最前面的元素
void sort() 将链表从小到大排序
void remove (const T & val) 删除和 val 相等的元素
remove_if 删除符合某种条件的元素
void unique() 删除所有和前一个元素相等的元素
void merge(list <T> & x)将链表 x 合并进来并清空 x。要求链表自身和 x 都是有序的
void splice(iterator i, list <T> & x, iterator first, iterator last) 在位置 i 前面插入链表 x 中的区间 [first, last),并在链表 x 中删除该区间。链表自身和链表 x 可以是同一个链表,只要 i 不在 [first, last) 中即可

3.deque的用法
deque 也是顺序容器的一种,同时也是一个可变长数组。要使用 deque,需要包含头文件 deque。所有适用于 vector 的操作都适用于 deque。
push_back 从尾部插入元素
push_front 从头部插入元素
pop_back 从尾部删除元素
pop_front 从头部删除元素
它有两种 vector 没有的成员函数:
void push_front (const T & val); //将 val 插入容器的头部
void pop_front(); //删除容器头部的元素

distance函数可以求出当前的迭代器指针it距离头部的位置,也就是容器的指针

用法: distance(v1.begin(), it)

4.stack的用法
size(); 大小
empty(); 是否为空
void pop(); 弹出(即删除)栈顶元素
T & top(); 返回栈顶元素的引用。通过此函数可以读取栈顶元素的值,也可以修改栈顶元素
void push (const T & x); 将 x 压入栈顶

5.queue和priority_queue
queue
queue 就是“队列”。队列是先进先出的,和排队类似。队头的访问和删除操作只能在队头进行,添加操作只能在队尾进行。不能访问队列中间的元素。
queue 同样也有和 stack 类似的 pushpoptop 函数。区别在于,queue 的 push 发生在队尾,pop 和 top 发生在队头。

priority_queue
priority_queue 是“优先队列”。它和普通队列的区别在于,优先队列的队头元素总是最大的——即执行 pop 操作时,删除的总是最大的元素;执行 top 操作时,返回的是最大元素的引用。

priority_queue<int>默认定义int类型的最大值队列
priority_queue<int, vector<int>, less<int>>定义int型的最大值优先队列
priority_queue<int, vector<int>, greater<int>>定义int型的最小值队列

priority_queue 默认的元素比较器是 less 。也就是说,在默认情况下,要放入 priority_queue 的元素必须是能用“<”运算符进行比较的,而且 priority _queue 保证以下条件总是成立:对于队头的元素 x 和任意非队头的元素 y,表达式“x<y”必为 false。

priority_queue 的第三个类型参数可以用来指定排序规则。
priority_queue 队头的元素只能被查看或者修改,不能被删除。

6.pair用法
pair实例化出来的类都有两个成员变量,一个是 first, 一个是 second。
STL 中还有一个函数模板 make_pair,其功能是生成一个 pair 模板类对象。make_pair 的源代码如下:

template <class T1, class T2>
pair<T1, T2 > make_pair(T1 x, T2 y)
{
    return ( pair<T1, T2> (x, y) );
}

下面的程序演示了 pair 和 make_pair 的用法。

#include <iostream>
using namespace std;
int main()
{
    pair<int,double> p1;
    cout << p1.first << "," << p1.second << endl; //输出  0,0   
    pair<string,int> p2("this",20);
    cout << p2.first << "," << p2.second << endl; //输出  this,20
    pair<int,int> p3(pair<char,char>('a','b'));
    cout << p3.first << "," << p3.second << endl; //输出  97,98
    pair<int,string> p4 = make_pair(200,"hello");
    cout << p4.first << "," << p4.second << endl; //输出  200,hello
    return 0;
}

7.map的用法

基本操作:

C ++ Maps是一种关联式容器,包含“关键字/值”对
begin()返回指向地图右侧的继承器
clear()删除所有元素
begin()返回指向地图右侧的继承器
clear()删除所有元素
count()返回指定元素出现的次数
empty()如果​​map为空则返回true
end()返回指向地图末尾的继承器
equal_range()返回特殊的的继承器对
delete()删除一个元素
find()发现一个元素
get_allocator()返回地图的配置器
insert()插入元素
key_comp()返回比较元素key的函数
lower_bound()返回键值> =给定元素的第一个位置
max_size()返回可以容纳的最大元素个数
rbegin()返回一个指向地图尾部的逆向迭代器
rend()返回一个指向地图头部的逆向迭代器
size()返回地图中元素的个数
swap()交换两个地图
upper_bound()返回键值>给定元素的第一个位置
value_comp()返回比较元素value的函数

 

用法示例

    //通过pair<int, string>(1,”chenhua“) 构造pair元素
    map1.insert(pair<int, string>(0,"zero"));
    //通过make_pair构造pair元素
    map1.insert(make_pair(1,"m"));
    //通过value_type构造pair元素
    map1.insert(map<int, string>::value_type(3,"ming"));   
    //[]直接插入
    map1[4] = "hello";

 

8、set的用法
C++的set容器,其中包含的元素是唯一的,而且是有序的。
C++的set容器,是按照顺序插入的,不能在指定位置插入。
C++的set容器,其结构是红黑二叉树,插入数据的效率比vector快

创建集合的方式:

set<int> 创建默认的从小到大的int类型的集合
set<int,less<int>> 创建一个从小打到大的int类型的集合
set<int,greater<int>>创建一个从大到小的int类型的集合

set提供了inserterase函数,用来对元素进行插入和删除操作。

set容器提供了多个函数用来查找元素:
iterator find(const key_type& __k) find函数查找元素为k的迭代器位置
iterator lower_bound(const key_type& __k) lower_bound函数查找小于等于元素k的迭代器位置
iterator upper_bound(const key_type& __k) upper_bound函数查找大于元素k的迭代器位置
pair<iterator,iterator> equal_range(const key_type& __k) equal_range函数返回一个pair类型,第一个属性表示大于等于k的迭代器位置,第二个是大于k的迭代器位置

9.multiset容器
multiset容器,与set容器相似,但是multiset容器中的元素可以重复。另外,他也是自动排序的,容器内部的值不能随便修改,因为有顺序的。

multimap容器,与map容器的唯一区别是:multimap支持多个键值。