STL介绍

    先前参加了蓝桥杯的省赛,侥幸进入了国赛,本来是准备全心考研,但又多了这么一次机会,那就好好准备吧。此前对于算法,我一直都是用纯C来编写。经过辅导老师点拨,国赛时纯C的算法很大可能会超时,所以为了能取得好成绩,还是了解一下吧。

一,STL的组成部分

  1).容器(containers):是一种数据结构容器,使用类模板的方法提供,我们可以方便的进行数据的存储操作

  2).适配器(adapters):以序列式容器为基础,提供的栈,队列和优先级队列的这种容器

  3).迭代器(iterator):类似于指针,用来操作容器的元素

  4).算法(algorithm):包含一系列常见的算法

  5).空间适配器(allocator):其中的主要工作包括两部分:1,对象的创建和销毁。2,内存的创建与释放

  6).仿函数(function):仿函数又称为函数对象,其实就是好重载了()操作符的struct,没有什么特别的地方

二,STL的容器

  1,序列式容器

   1).每个元素都有固定的位置,取决于插入时机和地点。与元素值无关。

   2).vector(向量):底层数据结构是数组,可以随机存取数据元素(用索引直接存取),数组的尾部添加和移除元素很快,但在头部和中部插入元素比较耗时。

//vector容器简单用法


//输入
#include <iostream>
#include <vector> 
#include <stdio.h>
using namespace std;
int main(void)
{
	//vector(动态数组)有内存管理的机制,
	//也就是说对于插入和删除,vector可以动态调整所占用的内存空间。
	vector<int> tmp;
	for(int i=0;i<10;i++)
	{
		tmp.push_back(i);
	}
	//获得tmp的迭代器it,it初始化为tmp的开头,遍历到tmp的结尾 
	for(vector<int>::iterator it = tmp.begin();it!=tmp.end();it++)
	{
		cout<<*it<<" "; //对迭代器it进行解引用 
	}
	return 0;
}
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;
void print(vector<int> tmp);
bool comp(const int &a,const int &b)
{
	return a>b;
}
int main(void)
{
	vector<int> tmp;
	for(int i=0;i<10;i++)
	{
		tmp.push_back(rand()%100);
	}
	print(tmp);
	//颠倒 
	reverse(tmp.begin(),tmp.end());
	print(tmp); 
	//默认升序 
	sort(tmp.begin(),tmp.end());
	print(tmp);
	//降序 
	sort(tmp.begin(),tmp.end(),comp);
	print(tmp);
	return 0;
}

void print(vector<int> tmp)
{
	for(vector<int>::iterator it = tmp.begin();it!=tmp.end();it++)
	{
		cout<<*it<<" ";
	}
	cout<<endl;
}
    
   3).deque(双端队列):底层数据结构是数组,可以随机存取数据元素,在数组的头部和尾部插入和删除元素很快。

    

/*
	deque和vector一样,采用线性表,与vector唯一不同的是,deque采用的分块的线性存储结构,
每块大小一般为512字节,称为一个deque块,所有的deque块使用一个Map块进行管理,
每个map数据项记录各个deque块的首地址,这样以来,deque块在头部和尾部都可已插入和删除元素,
而不需要移动其它元素。使用push_back()方法在尾部插入元素,使用push_front()方法在首部插入元素,
使用insert()方法在中间插入元素。
*/

#include <iostream>
#include <deque>
using namespace std;
int main(void)
{
	deque<int> tmp;
	for(int i=0;i<10;i++)
	{
		if(i%2==0) tmp.push_front(i);
		else tmp.push_back(i);
	}
	tmp.insert(tmp.begin+4,101);  //用insert从中间插入	 
	//可以使用下标遍历,此处使用迭代器
	for(deque<int>::iterator it = tmp.begin();it!=tmp.end();it++)
		cout<<*it<<"  "; 
	return 0;
}

   4).list(列表):底层数据结构是双向链表,不提供随机存取数据元素(需要按顺序走到要存取的元素),在任何位置插入和删除都很快,只需要移动一下指针。

    

#include <iostream>
#include <list>
using namespace std;
int main(void)
{
	list<int> tmp;
	tmp.push_back(5);
	tmp.push_front(2);
	tmp.push_back(2);
	tmp.push_front(32);
	tmp.push_back(6);
	tmp.push_front(7);
	tmp.push_back(0);
	tmp.push_front(1);
	for(list<int>::iterator it = tmp.begin();it!=tmp.end();it++)
		cout<<*it<<" ";
	cout<<endl;
	//排序 
	tmp.sort();
	for(list<int>::iterator it = tmp.begin();it!=tmp.end();it++)
		cout<<*it<<" ";
	cout<<endl;
	//排除重复的(得先排序) 
	tmp.unique();
	for(list<int>::iterator it = tmp.begin();it!=tmp.end();it++)
		cout<<*it<<" ";
	cout<<endl;
	return 0;
}

  2,关联式容器

   1).元素位置取决于特定的排序准则,和插入的顺序无关,底层数据结构是二叉树。


   2).set(集合):内部元素依据其值自动排序,set内相同的数值元素只能出现一次。

    

/*
    set是用红黑树的平衡二叉索引树的数据结构来实现的,插入时,它会自动调节二叉树排列,
把元素放到适合的位置,确保每个子树根节点的键值大于左子树所有的值、小于右子树所有的值,
插入重复数据时会忽略。set迭代器采用中序遍历,检索效率高于vector、deque、list,
并且会将元素按照升序的序列遍历。set容器中的数值,一经更改,set会根据新值旋转二叉树,
以保证平衡,构建set就是为了快速检索
   multiset,multiset与set的不同之处就是key可以重复,
以及erase(key)的时候会删除multiset里面所有的key并且返回删除的个数。
*/
#include <iostream>
#include <set>
using namespace std;
struct Comp{ //自定义比较函数(元素本身不是结构体)
	
	bool operator()(const int &a,const int &b)
	{
		return a>b;
	}
};
int main(void)
{
	set<int> tmp;
	tmp.insert(5);
	tmp.insert(6);
	tmp.insert(1);
	tmp.insert(3);
	tmp.insert(4);
	tmp.insert(2);
	tmp.insert(6);
	//自动升序 
	for(set<int>::iterator it = tmp.begin();it!=tmp.end();it++)
	{
		cout<<*it<<"  ";
	}
	cout<<endl;
	//降序遍历 
	for(set<int>::reverse_iterator it = tmp.rbegin();it!=tmp.rend();it++)
	{
		cout<<*it<<"  ";
	}
	cout<<endl;
	set<int,Comp> tmpC;
	tmpC.insert(5);
	tmpC.insert(6);
	tmpC.insert(1);
	tmpC.insert(3);
	tmpC.insert(4);
	tmpC.insert(2);
	tmpC.insert(6);
	//自定义比较函数,降序 
	for(set<int,Comp>::iterator it = tmpC.begin();it!=tmpC.end();it++)
	{
		cout<<*it<<"  ";
	}
	cout<<endl;
	return 0;
} 
   3).multiset(多重集合):内部元素依据其值自动排序,set内可以出现重复的元素。

   4).map(映射):map的元素是成对的键值对,内部元素的值依据键自动排序,键只可以出现一次

/*
map也是使用红黑树,他是一个键值对(key:value映射),便利时依然默认按照key程序的方式遍历,同set。
*/
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main(void)
{
	map<string,double> tmp;
	tmp["A"] = 12.5;
	tmp["B"] = 35.2;
	tmp["D"] = 45.2;
	tmp["C"] = 452.1;   //遍历时,按照键排序输出 
	for(map<string,double>::iterator it = tmp.begin(); it != tmp.end(); ++it)
	{
		cout<<(*it).first<<"->"<<(*it).second<<endl;
	}
	return 0;
}


三,STL的适配器

  1),什么是适配器

    STL提供了三种适配器stack,queue和priority_queue。这些适配器是包装了序列式容器(vector,deque,list)中的一种。

因此所谓的适配器就是序列式容器的包装器,注意:适配器没有提供迭代器。


  2).stack(栈)

  栈可以使用序列式容器中的vector,deque,list中的任意一种作为其底层的数据结构。默认是使用deque来实现的stack。   

#include <iostream>
#include <stack>
using namespace std;
int main(void)
{
	stack<int> tmp;
	tmp.push(2);
	tmp.push(1);
	tmp.push(3);
	tmp.push(4);
	tmp.push(5);
	tmp.push(28);
	tmp.push(7);
	cout<<"size is:"<<tmp.size()<<endl; 
	while(!tmp.empty())  //栈不为空 ,适配器没有迭代器 
	{
		cout<<tmp.top()<<"  ";
		tmp.pop(); //移除栈顶元素 
	}
	return 0;
}

  3).queue(队列)

  队列可以使用deque和list中的任意一种作为其底层的数据结构。默认是使用deque来实现的queue。
    

  4).priority_queue(优先队列)

  优先队列也是一种队列,不过在进入队列之后会对元素进行排序,可以使用vector和deque来实现其底层结构,默认是使用

vector来实现priority_queue。


#include <iostream>
#include <queue>
using namespace std;
int main(void)
{
	 priority_queue<int> tmp;
     tmp.push(1);
     tmp.push(3);
     tmp.push(2);
     tmp.push(8);
     tmp.push(9);
     tmp.push(0);
 
     cout << "size: " << tmp.size() << endl;
     while(!tmp.empty())//如果优先队列为空,则返回真
     {
         cout << tmp.top()<<"  ";  //返回优先队列中有最高优先级的元素
         tmp.pop(); //删除第一个元素
     }
     return 0;
}

  5).序列式容器和适配器比较


猜你喜欢

转载自blog.csdn.net/qq_37437983/article/details/79963500