C++中的容器(STL容器)

定义

容器:能够操作多种数据结构和算法的模板类和函数库。能够像现实中的容器一样存放各种类型的对象,一个容器中的所有对象必须是同一个类型的。

容器分为两大类:顺序容器、关联容器。

顺序容器

顺序容器有以下三种:vector(向量)、 deque(双队列)、list(列表)。

它们之所以被称为顺序容器,是因为元素在容器中的位置同元素的值无关,即容器不是排序的。将元素插入容器时,指定在什么位置(尾部、头部或中间某处)插入,元素就会位于什么位置。

1、vector
连续存储结构,每个元素在内存上是连续的;
支持高效的随机访问和在尾端插入/删除操作,但其他位置的插入/删除操作效率低下;

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

3、list
非连续存储结构,具有双链表结构,每个元素维护一对前向和后向指针,因此支持前向/后向遍历。
支持高效的随机插入/删除操作,但随机访问效率低下,且由于需要额外维护指针,开销也比较大。

顺序容器的选择:
a、若需要随机访问操作,则选择vector;
b、若已经知道需要存储元素的数目, 则选择vector;
c、若需要随机插入/删除(不仅仅在两端),则选择list
d、只有需要在首端进行插入/删除操作的时候,才选择deque,否则都选择vector。
e、若既需要随机插入/删除,又需要随机访问,则需要在vector与list间做个折中。
f、当要存储的是大型负责类对象时,list要优于vector;当然这时候也可以用vector来存储指向对象的指针,同样会取得较高的效率,但是指针的维护非常容易出错,因此不推荐使用。

注意:vector与deque的迭代器支持算术运算,list的迭代器只能进行++/–操作,不支持普通的算术运算。

关联容器

关联容器有以下四种:set(集合)、multiset(多重集合)、map(映射)、multimap(多重映射)。

关联容器内的元素是排序的。插入元素时,容器会按一定的排序规则将元素放到适当的位置上,因此插入元素时不能指定位置。

默认情况下,关联容器中的元素是从小到大排序(或按关键字从小到大排序)的,而且用<运算符比较元素或关键字大小。因为是排好序的,所以关联容器在查找时具有非常好的性能。

除了以上两类容器外,STL 还在两类容器的基础上屏蔽一部分功能,突出或增加另一部分功能,实现了三种容器适配器:stack(栈)、queue(队列)、priority_queue(优先级队列 )。

容器的函数

所有容器都有以下两个成员函数:
int size():返回容器对象中元素的个数。
bool empty():判断容器对象是否为空。

顺序容器和关联容器还有以下成员函数:
begin():返回指向容器中第一个元素的迭代器。
end():返回指向容器中最后一个元素后面的位置的迭代器。
rbegin():返回指向容器中最后一个元素的反向迭代器。
rend():返回指向容器中第一个元素前面的位置的反向迭代器。
erase(…):从容器中删除一个或几个元素。
clear():从容器中删除所有元素。

如果一个容器是空的,则 begin() 和 end() 的返回值相等,rbegin() 和 rend() 的返回值也相等。

顺序容器还有以下常用成员函数:
front():返回容器中第一个元素的引用。
back():返回容器中最后一个元素的引用。
push_back():在容器末尾增加新元素。
pop_back():删除容器末尾的元素。
insert(…):插入一个或多个元素。该函数参数较复杂,此处省略。

示例

(这里只列举一些容器以及一些函数用法)
顺序容器:
vector 容器

void main()   //遍历、删除、插入
{
    
    
	vector<int> v1;
	v1.push_back(10);  //copy 到申请的容器
	v1.push_back(20); 
	v1.push_back(30); 

	//访问容器,定义一个迭代器:   相当于一个指针
	//正向遍历
	for(vector<int>::iterator it = v1.begin();it != v1.end();it++)
	{
    
    
		cout<<*it<<endl;
	}
	//逆向遍历
	for(vector<int>::reverse_iterator rit = v1.rbegin();rit != v1.rend();rit++)
	{
    
    
		cout<<*rit<<endl;
	}
	//区间删除
	v1.erase(v1.begin(),v1.begin()+2);
	//指定位置删除
	v1.erase(v1.begin());
	//遍历删除
	for(vector<int>::iterator dit = v1.begin();dit != v1.end();)
	{
    
    
		if(*dit == 2)
		{
    
    
			v1.erase(dit);   //当删除迭代器所指向元素时,erase让it自下移
		}
		else
		{
    
    
			dit++;
		}
	}
	//插入元素
	v1.insert (v1.begin(),100);    //头部插入数值100
	v1.insert (v1.end (),200);    //尾部插入数值200
	return;
}

deque 容器

void printd(deque<int> &d)
{
    
    
	for(deque<int>::iterator it = d.begin(); it != d.end();it++)
	{
    
    
		cout<<"元素"<<*it<<endl;
	}
}
void main()
{
    
    
	deque<int> d;
	d.push_back(1);  //在容器末尾增加新元素
	d.push_back(2);  
	d.push_front(3);  //在容器头尾增加新元素
	d.push_front(4);
	printd(d);

	deque<int>::iterator it = find(d.begin(),d.end(),3);  //查找指定元素3  找到时,返回该元素的迭代器;找不到时,返回end()。  
	if(it != d.end())
	{
    
    
		cout<<"3与第一个元素的距离为:"<<distance(d.begin (),it)<<endl;
	}

}

关联容器:
set容器

void main()
{
    
    
	set<int> set1;
	//循环插入
	for(int i = 0;i < 3;i ++)
	{
    
    
		int tmp = rand() % 5;
		set1.insert(tmp);
	}
	//遍历打印集合
	for(set<int>::iterator it = set1.begin();it != set1.end(); it++)
	{
    
    
		cout<<*it<<endl;
	}
	//删除集合
	while(!set1.empty())
	{
    
    
		set<int>::iterator item = set1.begin();
		set1.erase(item);
	}
	return;
}

map容器

//元素的添加、遍历、删除等基本操作
void main()
{
    
    
	//1、创建map对象
	map<int, string> map1;
	//方法1  添加元素  pair是一个有两个元素的结构体,方便使用,类似map :键值可以随意使用  
	//pair可以用来当做map的键值来插入 pair<T1,T2> p1 创建一个空的pair对象,有两个元素T1和T2,采用值初始化
	map1.insert(pair<int, string>(1,"hehe"));
	map1.insert(pair<int, string>(2,"xixi"));
	//方法2   添加元素 make_pair
	//make_pair
	map1.insert(make_pair(3,"haha"));
	map1.insert(make_pair(4,"huhu"));
	//方法3  添加元素
	map1.insert(map<int, string>::value_type(5,"kaka"));
	map1.insert(map<int, string>::value_type(6,"yiyi"));
	//方法4  数组方式插入数据
	map1[7] = "yaya";
	//容器遍历(迭代器)
	for(map<int, string>::iterator it = map1.begin();it != map1.end(); it++)
	{
    
    
		cout<<it->first<<"\t"<<it->second <<endl;
	}
	cout<<"遍历结束"<<endl;

	//容器的删除
	while(!map1.empty())
	{
    
    
		map<int, string>::iterator it = map1.begin();
		map1.erase(it);
	}

	//map查找
	map<int, string>::iterator it1 = map1.find(2);
	if(it1 != map1.end())
	{
    
    
		cout<<"不存在"<<endl;
	}
	else
	{
    
    
		cout<<it1->first<<"\t"<<it1->second<<endl;
	}

}

猜你喜欢

转载自blog.csdn.net/qq_46485161/article/details/114992407
今日推荐