1.STL ---list简单介绍
list 是顺序容器的一种。list 是一个双向链表。使用 list 需要包含头文件 list。双向链表的每个元素中都有一个指针指向后一个元素,也有一个指针指向前一个元素,如图1所示。
在 list 容器中,在已经定位到要增删元素的位置的情况下,增删元素能在常数时间内完成。如图2所示,在 ai 和 ai+1 之间插入一个元素,只需要修改 ai 和 ai+1 中的指针即可。
图1 :双向链表
图2:在双向链表中插入元素
list 容器不支持根据下标随机存取元素。
list 的构造函数和许多成员函数的用法都与 vector 类似,此处不再列举。除了顺序容器都有的成员函数外,list 容器还独有如表 1 所示的成员函数(此表不包含全部成员函数,且有些函数的参数较为复杂,表中只列出函数名)。
成员函数或成员函数模板 | 作 用 |
---|---|
void push_front(const T & val) | 将 val 插入链表最前面 |
void pop_front() | 删除链表最前面的元素 |
void sort() | 将链表从小到大排序 |
void remove (const T & val) | 删除和 val 相等的元素 |
remove_if | 删除符合某种条件的元素 |
void unique() | 删除所有和前一个元素相等的元素 |
void merge(list <T> & x) | 将链表 x 合并进来并清空 x。要求链表自身和 x 都是有序的 |
void splice(iterator i, list <T> & x, iterator first, iterator last) | 在位置 i 前面插入链表 x 中的区间 [first, last),并在链表 x 中删除该区间。链表自身和链表 x 可以是同一个链表,只要 i 不在 [first, last) 中即可 |
表1中列出的成员函数有些是重载的,如 unique、merge、splice 成员函数都不止一个, 这里不再一一列举并解释。后面对于其他容器以及算法的介绍,对于有重载的情况也不再指出。要详细了解 STL,还需要查阅专门的 STL 手册,或查看编译器提供的联机帮助。
STL 中的算法 sort 可以用来对 vector 和 deque 排序,它需要随机访问迭代器的支持。因为 list 不支持随机访问迭代器,所以不能用算法 sort 对 list 容器排序。因此,list 容器引入了 sort 成员函数以完成排序。
2.Coding
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
/*仿函数的使用
仿函数就是使一个类的使用看上去就像一个函数,其实现就是在
类中实现operator()这个类就有了类似函数的行为,就是一个仿函数的类
*/
/*定义一个类*/
class A
{
private:
int n;
public:
A(int n_)
{
n=n_;
}
/*利用函数实现重载---仿函数*/
/*重载 <*/
friend bool operator < (const A &a1, const A & a2);
friend bool operator == (const A &a1, const A & a2);
friend bool operator > (const A &a1,const A & a2);
friend ostream & operator << (ostream &o,const A &a);
};
/*友函数实现*/
bool operator < (const A & a1,const A &a2){
return a1.n<a2.n;
}
bool operator == (const A & a1,const A &a2){
return a1.n==a2.n;
}
bool operator>(const A & a1,const A &a2){
return a1.n<a2.n;
}
/*输出流重载函数实现*/
ostream & operator << (ostream &o,const A &a)
{
o<<a.n;
return o;
}
/*定义一个类模板函数--用来打印任意的输出值*/
template <class T>
void Print(T first, T last)
{/*类似实现迭代起的功能*/
for(;first !=last;++first)
cout<<*first<<" ";
cout<<endl;
}
/**
* 主要用来完程list 测试
* 注意:STL 中的算法sort可以用来对vector 和deque 排序,他需要迭代器的支持,
* 但是 list不支持随机访问迭代器,所以不能使用sort对list的容器进行排序。
* 所以,list容器引入了sort成员函数进行对list进行排序
*/
void test()
{
A a[5]={1,4,8,5,7};
A b[7]={10,30,20,30,30,40,40};
list<A> lst1(a,a+5),lst2(b,b+7);
cout<<"输出list" <<endl;
lst1.sort();
cout<<"输出lis1排序之后的list"<<endl;
cout<<"1)";
Print(lst1.begin(),lst1.end());
lst1.remove(1);
cout<<"2)";
Print(lst1.begin(),lst1.end());
/*删除所有和前一个相等的元素*/
lst2.unique();
Print(lst2.begin(),lst2.end());
/*把lst2合并到lst1,并且清空lst2*/
lst1.merge(lst2);
Print(lst1.begin(),lst1.end());
Print(lst2.begin(),lst2.end()); //已经被清空
/*将 lst1 前后颠倒*/
lst1.reverse();
Print(lst1.begin(),lst1.end());
/*在lst2中插入元素*/
lst2.insert(lst2.begin(),a+1,a+4);//在lst2的开始位置插入a+1 开始到a+4
Print(lst2.begin(),lst2.end());//lst=4,8,5
/*利用find进行遍历*/
list<A>::iterator p1,p2,p3;
p1=find(lst1.begin(),lst1.end(),30);//遍历链表查找所需要的值,返回的类型是迭代器
p2=find(lst2.begin(),lst2.end(),4);
p3=find(lst2.begin(),lst2.end(),5);
lst1.splice(p1,lst2,p2,p3);//将[p2,p3]插入到p1之前,并从lst2中删除[p2,p3]
cout<<"8)";Print(lst1.begin(),lst1.end());
cout<<"9)";Print(lst2.begin(),lst2.end());
}
int main()
{
test();
return 0;
}
运行结果:
3.本实验的简单通用makefile
src=$(wildcard *.cpp)
targets=$(patsubst %.cpp,%,$(src))
CC =g++
CFLAGS = -Wall -g
all:$(targets)
$(targets):%:%.cpp
$(CC) $< -o $@ $(CFLAGS) -lpthread
.PHONY:clean all
clean:
-rm -rf $(targets)