c++标准库中几个常见的数据结构的区别和应用规则

https://blog.csdn.net/gogokongyin/article/details/51178378

vector,list,deque

使用区别:

1)如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector

2)如果你需要大量的插入和删除,而不关心随机存取,则应使用list
3)如果你需要随机存取,而且关心两端数据的插入和删除,则应使用deque

1.Vector

Vecor在数组中有很大的应用,它拥有一段额内存空间,并且起始地址不变,因此可以非常好的支持随机存取,即[]操作符,但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝,另外当该数组的内存空间不够时,需要重新申请一块足够大的内存并进行内存的拷贝,因此效率不高。

总结:优点:可进行随即存取,[]操作

         缺点:进行插入很删除时会造成内存块的拷贝,效率较低

基本操作:

(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();

算法:

使用reverse将元素翻转,需头文件#include<algorithm>

reverse(vec.begin(),vec.end());将元素翻转,即逆序排列!

(2)使用sort排序:需要头文件#include<algorithm>,

sort(vec.begin(),vec.end());(默认是按升序排列,即从小到大).

可以通过重写排序比较函数按照降序比较,如下:

定义排序比较函数:

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

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

2.       List  // https://blog.csdn.net/zhouzhenhe2008/article/details/77428743

List是数据结构中的双向链表,因此它的内存空间是可以不连续的,通过指针进行数据的访问,这个特点使它的随机存取变得没有效率,不提供[]操作符的重载,但由于链表的特点,它可以以很好的效率支持任意地方的删除很插入。

总结: 优点:可以很好的支持任意地方的插入和删除

       缺点:不支持[]操作

基本操作:#include<list>

typedef   list<int > list_t;

定义list的类型

list_t  List;//定义一个空的链表

list_t  List(count);//建一个含count个默认值是0的元素的链表

list_t  List(count,info); //建一个含count个默认值是info的元素的链表

list_t List(List2);  //建一个的copy链表

list_t  List(List2.begin(),List2.end());//含区间的元素[First,Last]

List.push_back(a);//添加元素到末尾

list_t::iterator iter;   //元素遍历

for(iter = List.begin(); iter != List.end() ;iter++)

{

std::cout<< iter->nNumber <<std::endl;

}

c++的stl list 提供pop_back()函数来删除最后一个元素。

List.pop_back();  //删除末尾元素

List.clear();//删除所有元素

list_t::iterator iter; for(iter = List.begin(); iter !=List.end() ;)

{

//这里可以做是否内存或者资源的操作

//

iter = List.erase(iter);

//iter指向了下一个元素

} // //遍历删除法,一个一个删除,这样的好处是,如果元素有申请内容或者系统资源,我们可以把他释放了,避免资源泄漏。

iter = List.insert(iter , info);// 插入,插入后iter指向新插入的元素。

list_t::iterator iter

iter = std::find(List.begin(),List.end(), a);

if(iter != List.end())

{

std::cout<<"find it"<<std::endl;

}

else

{

std::cout<<"not find it"<<std::endl;

}

List.sort();//排序

3. Deque

deque是一个double-ended   queue,它的具体实现不太清楚,但知道它具有以下两个特点:它支持[]操作符,也就是支持随即存取,并且和vector的效率相差无几,它支持在两端的操作:push_back,push_front,pop_back,pop_front等,并且在两端操作上与list的效率也差不多。

连续存储结构,即其每个元素在内存上也是连续的,类似于vector,不同之处在于,deque提供了两级数组结构, 第一级完全类似于vector,代表实际容器;另一级维护容器的首位地址。这样,deque除了具有vector的所有功能外,还支持高效的首/尾端插入/删除操作。
deque 双端队列 double-end queue
deque是在功能上合并了vector和list。

优点:

(1)    随机访问方便,即支持[ ]操作符和vector.at()
(2) 在内部方便的进行插入和删除操作
(3) 可在两端进行push、pop

缺点:占用内存多

4.Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性map内部的实现自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能。

5. set是集合,set中不会包含重复的元素,这是和vector的第一个区别,第二个区别是set内部用平衡二叉树实现,便于元素查找,而vector是使用连续内存存储,便于随机存取。
因此在实际使用时,如何选择这几个容器中哪一个,应根据你的需要而定,一般应遵循下面
的原则:
1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。

4、如果你要存储一个数据字典,并要求方便地根据key找value,那么map是较好的选择

5、如果你要查找一个元素是否在某集合内存中,则使用set存储这个集合比较好

猜你喜欢

转载自blog.csdn.net/wonitawonitawonita/article/details/79924575