一.sort函数
1、头文件:#include < algorithm>;
2、它使用的排序方法是类似于快排的方法,时间复杂度为n*log2(n);
3、Sort函数有三个参数:(第三个参数可不写)
(1)第一个是要排序的数组的起始地址。
(2)第二个是结束的地址(最后一位要排序的地址的下一位地址)。
(3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。升序:sort(begin,end,less<data-type>());降序:sort(begin,end,greater<data-type>())。
二.lower_bound函数
头文件: #include<algorithm>
函数模板: 如 binary_search()
函数功能: 函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!
返回查找元素的第一个可安插位置,也就是“元素值>=查找值”的第一个元素的位置
三.upper_bound函数
头文件:#include<algorithm>
函数模板: 如binary_search()
函数功能:函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置。
同样,如果插入元素大于数组中全部元素,返回的是last。(注意:数组下标越界)
返回查找元素的最后一个可安插位置,也就是“元素值>查找值”的第一个元素的位置。
四.不定长数组:vector
头文件:#include<vector>
函数功能:vector就是一个不定长数组。不仅如此,它把一些常用的操作封装在了vector类型内部。例如,若a是一个vector,可以用a.size()读取它的大小,a.resize()改变大小,a.push_back()向尾部添加元素,a.pop_back()删除最后一个元素,a.empty()测试是否为空。
vector是一个模板类,所以需要用vector<int> a或者vector<double> b这样的方式来声明一个vector。vector<int>是一个类似于int a[]的整型数组。vector看上去像“一等公民”,因为他们可以直接赋值,还可以作为函数的参数或返回值,而无须像传递数组那样另外用一个变量指定元素个数。
五.集合:set
头文件:#include<set>
函数功能:set就是数学上的集合——每个元素最多只出现一次。和sort一样,自定义类型也可以构造set,但同样必须定义“小于”运算符。set<string> dict用来定义一个string集合,dict.insert(buf)用来插入一个字符串(由于string已经定义了“小于”运算符,直接使用set保存字符串集合即可)由于set中元素会按从小到大排序这一性质,则set中的字符串会按从小到大排好序。
六.映射:map
头文件:#include<map>
函数功能:map就是从键(key)到值(value)的映射。因为重载了[ ]运算符,map像数组的“高级版”。例如可以用一个map<string,int>month_name来表示“月份名字到月份编号”的映射,然后用month_name["July"]=7这样的方式来赋值。
为了使用方便,可以对模板类进行一下类型定义,
typedef map<int,CString> UDT_MAP_INT_CSTRING;
UDT_MAP_INT_CSTRING enumMap;
自动建立Key - value的对应。key 和 value可以是任意你需要的类型。
根据key值快速查找记录,查找的复杂度基本是Log(N),如果有1000个记录,最多查找10次,1,000,000个记录,最多查找20次。
快速插入Key -Value 记录,insert()函数。
获取map的大小,size()函数。
快速删除记录
根据Key 修改value记录。
用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了。
用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。
查找map中是否包含某个关键字条目用find()方法,传入的参数是要查找的key,在这里需要提到的是begin()和end()两个成员,
分别代表map对象中第一个条目和最后一个条目,这两个数据的类型是iterator.
移除某个map中某个条目用erase(),该成员方法的定义如下:
iterator erase(iterator it);//通过一个条目对象删除
iterator erase(iterator first,iterator last)//删除一个范围
size_type erase(const Key&key);//通过关键字删除
map中的元素是自动按Key升序排序,所以不能对map用sort函数;这里要讲的是一点比较高深的用法了,排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int 型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过 不去,所以需要定义一个“小于”运算符“。
还要说明的是,map中由于它内部有序,由红黑树保证,因此很多函数执行的时间复杂度都是log2N的,如果用map函数可以实现的功能,而STL Algorithm也可以完成该功能,建议用map自带函数,效率高一些。
下面说下,map在空间上的特性,否则,估计你用起来会有时候表现的比较郁闷,由于map的每个数据对应红黑树上的一个节点,这个节点在不保存你的 数据时,是占用16个字节的,一个父节点指针,左右孩子指针,还有一个枚举值(标示红黑的,相当于平衡二叉树中的平衡因子),我想大家应该知道,这些地方 很费内存了吧,不说了……
map的基本操作函数:
C++ maps是一种关联式容器,包含“关键字/值”对
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
七.栈、队列与优先队列
1.栈:头文件:<stack>;
用stack<int> s 方式声明一个栈;
用push(),pop()实现元素的入栈,出栈操作,top()取栈顶元素(但不删除)。
2.队列:头文件:<queue>;
用queue<int> s 方式声明一个队列;
用push(),pop()实现元素的入队和出队操作,front()取队首元素(但不删除)。
3.优先队列:是一种抽象数据类型(Abstract Data Type,ADT),行为类似队列,但先出的元素不是先进的元素,而是队列中优先 级最高的元素。
头文件:<queue>;
用priority_queue<int> qp 来声明,这个pq是一个“越小的整数优先级越低的优先队列”;
用push(),pop()实现元素的入队,出队操作,top()取队首元素(但不删除)。
自定义类型也可以组成优先队列,但必须为每个元素定义一个优先级。这个优先级并不需要一个确定的数字,只需要能比较大小即可。只要元素定义了“小于”运算符,就可以使用优先队列。对于一些常见的优先队列,STL提供了更为简单的定义方法,例如,“越小的整数优先级越大的优先队列”可以写为"priority_queue<int,vector<int>,greater<int> >pq"。Attention:最后两个“>"不要写在一起,否则会被很多(但不是所有)编译器误认为是">>"运算符。