标准模板STL-概述

1. STL
(1)先回忆数据结构
从数据结构的学习中,我知道了有顺序表,链表,哈希表,顺序树,链式数等数据结
构可以用于存放数据。

在c中,这些数据结构都需要程序员自己实现,但是在面向对象的语言中,为了节省编
程者的开发时间,都提供了自己的定义的现成可用的数据结构,这些数据结构本质上还
是数组,链表,树(红黑树),哈希表等等。


(2)一个数据结构包含哪些内容
以我们之前学习的链表这个数据结构为例,它包含如下内容。

(1)容器:链表就是一个存放数据的容器,存储结构为链式存储,存放数据时,
	需要反映出被存储数据的逻辑结构

(2)遍历:向前向后索引节点就是遍历,遍历节点是能够访问数据的前提。当然对于
	遍历操作来说,除了可以使用迭代器外。

(3)算法:对链表中的数据的具体操作算法,增加,删除,查找,修改,排序

实际上对于高级语言自带的数据结构做的也是这些事情,但是这些事情不需要程序员
操心,我们只要学会使用就好,有了这些现成的数据结构,我们甚至都可以省去使用
自定义数组,因为这些数据结构本身就可以替代数组的功能。某些数据结构中本身就
是数组。

(1)c++的STL模板库与java中的集合
对于哪些封装好的现成可用的数据结构在c++中叫STL,java中称为集合,实际上是一
个东西,对于这些现成的数据结构来说,同样涉及如下三个方面的内容:

(1)容器

(2)遍历:普通指针,迭代器(智能指针),在c++和java都有迭代器,实现原理也
	是一样。

(3)算法:针对操作容器的算法,可以有如下3情况
	(1)可以自己实现操作容器的算法,实际上这么做没有必要
	(2)容器提供成员函数方式实现的算法
	(3)STL模板库提供全局算法函数
	
	
对于容器和集合的学习,重点在于学习怎么使用容器,比通过提供的算法去操作容器中
的数据。

不管是c++还是java的定义的数据结构,都是用到了泛型,在c++称为模板(函数模板和
类模板)。


2. 容器/迭代器/算法
(1)STL容器:
(1)存放内容的方式
	(1)存放副本:存放副本的特点是,修改副本并不会修改原对象的内容。

	(2)存放指针:使用指针好处是,效率很高,比存放副本的方式效率高很多。

	在java中没有存放副本的做法,存放的都是指针。

(2)STL容器分类
	(1)序列容器:以线性方式组织管理存放的数据,STL提供的顺序容器有:

		(1)vector<T>:以数组方式实现的数据结构,空间开辟于堆,
				其大小和容量可以根据实际情况改变。
		(2)deque<T>:可以在两头操作的特殊vector。
		(3)list<T>:使用链表实现的数据结构。
		(4)stack:栈,使用较少       
  			(5)queue:队列,使用较少
		(6)priority_queue:优先队列,使用较少  



	(2)关联容器:使用键值(key)与存储的内容关联起来,通过key去访问容
		器的中内容。STL提供的关联容器有:

		(1)map<key, T>:容器中一部分用于存放key值(key值不能重复)。
				另一部分用于存放key值对应的数据,把我们把
				Key和对应的数据我们称为键值对。

		(2)multimap<key, T>:同map,但是key值可以重复。

		(3)set<key>:数据本身就是key值,要求内容不能重复。

		(4)multiset<key>:同set,但是内容可以重复。	
				
	在c++这只提供了线性容器和关联容器这两类,但是在java提供了更加丰富的容器,
	(1)线性容器:vector,list,队列等
	(2)非线性容器:树(tree)结构的容器	
	(3)关联容器:map和set



(2)STL迭代器(普通指针)
(1)什么是迭代器
	迭代器就是封装好的智能指针,在学习前面的课程中,我们知道,智能指针
	就是对指针做了类封装的,c和c++中的指针就是最简单的迭代器。

(2)按功能对迭代器进行分类
	从功能上按照简单到复杂的顺序,迭代器分为如下及种类型,复杂类型的迭
	代器兼容简单类型的迭代器。

	(1)输入输出迭代器
		(1)用于读写一系列的对象,输入迭代器只能进行读操作,输出
			迭代只能进行写操作。
		(2)只能使用一次,第二次使用需要重新创建
		(3)实现的操作有:前后++,==,!=,*
		
	(2)前向迭代器
		兼容输入输出迭代器的功能,可以多次使用向前迭代器读写容器
		中的对象,迭代器支持++操作(前++/后++都支持)。
	
	(3)双向迭代器
		兼容前向迭代器的功能,但同时还允许向后遍历对象。所以迭代器
		还支持前后--的操作(前--/后--都支持)。
	
	(4)随机迭代器
		兼容双向迭代器的功能,但是同时允许随机访问。因为支持随机访
		问,所以必须支持如下操作:
		(1)iter+n和iter-n操作,iter[n]等价于*(iter+n)
		(2)iter+=n和iter-=n操作
		(3)迭代器相减,iter1-iter2操作
		(4)迭代器比较操作,比如iter1<iter2,iter1>iter2,
			iter1<=iter2,iter1>=iter2操作。
	
	以上功能是累积的,输入输出迭代器功能最弱,随机迭代器功能最强。
		

(3)在迭代器中使用泛型的问题
	定义迭代器对象时,需要指定访问的数据类型,比如:
		std::vector<int>::iterator iter;
	如果类型是泛型的话,定义迭代器是必须使用typename关键字,否者将会无法使用,比如:
		typename std::vector<T>::iterator iter;
	
	如果使用typedef给迭代器类型起别名时,如果涉及到泛型,那么同样的也需要使用
	typename关键字,比如:
		typedef typename std::vector<T>::iterator Iter;
		Iter iter;//使用别名定义迭代器


(3)如何获取迭代器
	(1)自定义迭代器,自定义迭代器可以按照自己要求实现以上4种类型中需要类型的迭代器。

	(2)从容器中获取迭代器
		STL容器自己提供了访问容器的迭代器。
		容器:		提供的迭代器类型
		vector              	随机              
	    deque               	随机         
        list                   	双向
		set                   	双向 
        multiset            	双向             
        map                 	双向
		multimap          	双向                        
 		stack                	不支持迭代器                  
  		queue              	不支持迭代器
		priority_queue   	不支持迭代器

		vector和deque之所以可以随机访问,因为他们本质上都是数组,我们前面讲过,数组
		本身就支持随机访问。
		
		list本质是链表,链表是不支持随机访问。

		set和map专门用于存放集合类数据,也是不支持随机访问的。

		栈,队列,优先队列之所以没有迭代器,因为都是在它们的头尾进行操作的,不需要遍
		历和随机访问。

	(3)使用容器以外迭代器
		比如iostream,istream, ostream, sstream等输入输出流提供的迭代器。



(3)算法函数
(1)容器提供的成员算法函数
	每种容器都提供了哪些成员算法函数,将在后面讲解,成员算法函数中,有些是直接定义的
	函数,有些就是通过函数模板实现的。

	容器提供的成员算法函数只针对本容器进行的。

(2)全局算法函数
	(1)查找类
		find(),find_end(),adjacent_find(),count(), mismatch(),
		seaech(), equal()。

	(2)修改类
		swap(), copy(), transform(). replace(), remove(), reverse(),
		rotate(), fill(), random/_shffle()。

	(3)排序
		sort() stable_sort(), binary_search(), merage(), min(), 
		max(), lexicographical_compare()。


	实际上一些普通的修改,查找等操作,直接通遍历访问每个元素就可以实现,
	不需要使用这些算法函数。全局算法函数大多都是通过函数模板实现的。
		
	全局算法函数可以针对不同种类的容器进行操作,但是也有些容器是无法通过
	全局算法函数无法操作的,这个时候只能通过容器的成员算法函数进行操作。
	

(4)STL的头文件
(1)容器头文件
	<vector>(单端数组), <deque>(双端数组), <list>, <map>, <set>, 
	<queque>(双端队列),<stack>(栈)	

(2)迭代器头文件
	<iterator>
	
	但是由于容器使用到了迭代器,因此容器头文件中也有包含<iterator>头文
	件,包含容器头文件时,可以不用包含迭代器头文件。	

	如果使用到了输入输出流提供的迭代器,需要包含输入输出流的头文件,比
	如<iostream>, <istream>, <ostream>,<sstream>。
	
(3)全局算法涉及头文件
	<algorithm>

	如果涉及函数对象,还需要<functional>头文件。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值