目录
国庆放假第三天,今天把stl的list学完。
lsit是一个带头双向循环链表。
遍历
list也可以用迭代器,范围for进行遍历,没有operator[ ]。
迭代器
list<int> s1;
s1.push_back(1);
s1.push_back(2);
s1.push_back(3);
s1.push_back(4);
list<int>::iterator it= s1.begin();
while (it != s1.end())
{
cout << *it << " ";
it++;
}
cout << endl;
范围for
list<int> s1;
s1.push_back(1);
s1.push_back(2);
s1.push_back(3);
s1.push_back(4);
for (auto ch : s1)
{
cout << ch << " ";
}
cout << endl;
逆置
逆置使用reverse():
list<int> s1;
s1.push_back(1);
s1.push_back(2);
s1.push_back(3);
s1.push_back(4);
s1.reverse();
for (auto ch : s1)
{
cout << ch << " ";
}
cout << endl;
交换
swap();
用来交换两个list,底层实现就是把连个list的头结点指针交换一下指向:
list<int> s1;
s1.push_back(1);
s1.push_back(2);
s1.push_back(3);
s1.push_back(4);
list<int> s3;
s3.push_back(4);
s3.push_back(3);
s3.push_back(2);
s3.push_back(1);
s1.swap(s3);
cout << "s1:" << " ";
for (auto ch : s1)
{
cout << ch << " ";
}cout << endl;
cout << "s3:" << " ";
for (auto ch : s3)
{
cout <<ch << " ";
}
cout << endl;
删除
remove
可以直接用remove删除指定的值:
list<int> s1;
s1.push_back(1);
s1.push_back(2);
s1.push_back(3);
s1.push_back(4);
s1.remove(3);
for (auto ch : s1)
{
cout << ch << " ";
}
cout << endl;
pop_back()
pop_back只能尾删,并且不能传参:
list<int> s1;
s1.push_back(1);
s1.push_back(2);
s1.push_back(3);
s1.push_back(4);
s1.pop_back();
for (auto ch : s1)
{
cout << ch << " ";
}
cout << endl;
快排
升序
list可以使用sort()进行快速排序:
list<int> s1;
s1.push_back(4);
s1.push_back(3;
s1.push_back(2);
s1.push_back(1);
s1.sort();
for (auto ch : s1)
{
cout << ch << " ";
}
cout << endl;
vector也可以进行快排,但是vector没有sort这个成员,算法库里有,包一下算法库的头文件
#include <algorithm>
然后看一下算法库里面的sort的用法:
可以看出来可以把vector的区间传给sort进行排序:
vector<int> s2;
s2.push_back(4);
s2.push_back(3);
s2.push_back(2);
s2.push_back(1);
sort(s2.begin(), s2.end());
for (auto ch : s2)
{
cout << ch << " ";
}
cout << endl;
如果list用算法库里的这个sort就会报错:
sort(s1.begin(), s1.end());
for (auto ch : s1)
{
cout << ch << " ";
}
cout << endl;
这是因为迭代器有好几种特性:
我们可以看一下sort和reverse:
vector是单链表,所以可以用sort,list是双链表,不能用sort只能用reverse()。但是vector可以用reverse();也就是单向的容器可以用随机的迭代器和双向迭代器,双向的容器只能用双向得迭代器。
降序
sort用了一个less仿函数实现升序,用greater实现降序:
greater<int> il;
s1.sort(il);
也可以用匿名对象的方式:
//greater<int> il;
//s1.sort(il);
s1.sort(greater<int>());
list sort和vector sort效率对比
如果数据少的话可以用list的sort进行排序,如果数据太多就不行了。我们可以实验一下,写一段如下代码:
void test2()
{
srand((size_t)time(0));
const size_t N = 100000;
vector<int> v;
v.reserve(N);
list<int> lit1;
list<int> lit2;
for (size_t i = 0; i < N; i++)
{
auto e = rand;
v.push_back((int)e);
lit1.push_back((int)e);
}
int begin1= clock();
sort(v.begin(), v.end());
int end1 = clock();
int begin2 = clock();
lit1.sort();
int end2 = clock();
cout << "vector sort:" << end1 - begin1 << endl;
cout << "list sort:" << end2 - begin2 << endl;
}
这段代码就是看一下vector进行快排和list进行快排的效率对比的:
可以看出list用快排占用栈帧比vecto使用快排大的多。因为vector是线性表,list是链表。
我们也可以让list1 sort一下,然后把list2给vector 进行代跑,等vector sort完再拷贝回来 然后对比list1和lit2的效率:
void test2()
{
srand((size_t)time(0));
const size_t N = 1000000;
//vector<int> v;
//v.reserve(N);
list<int> lit1;
list<int> lit2;
for (size_t i = 0; i < N; i++)
{
auto e = rand;
lit2.push_back((size_t)e);
lit1.push_back((size_t)e);
}
int begin1= clock();
vector<int >v(lit2.begin(), lit2.end());
sort(v.begin(), v.end());
lit1.assign(v.begin(), v.end());
int end1 = clock();
int begin2 = clock();
lit1.sort();
int end2 = clock();
cout << "list->vector sort:" << end1 - begin1 << endl;
cout << "list sort:" << end2 - begin2 << endl;
}
可以看出,明显经过vector 代跑的list2更快.
去重
去重就是去掉重复的值:
list<int> s3;
s3.push_back(5);
s3.push_back(4);
s3.push_back(3);
s3.push_back(2);
s3.push_back(1);
s3.push_back(1);
s3.push_back(1);
s3.unique();
for (auto ch : s3)
{
cout << ch << " ";
}cout << endl;
但是如果是无序的就不行,无序的需要先排序才能去重:
list<int> s3;
s3.push_back(5);
s3.push_back(4);
s3.push_back(1);
s3.push_back(3);
s3.push_back(2);
s3.push_back(1);
s3.push_back(1);
s3.sort(greater<int>());
s3.unique();
for (auto ch : s3)
{
cout << ch << " ";
}cout << endl;
接合
for (int i = 1; i <= 4; ++i)
mylist1.push_back(i); // mylist1: 1 2 3 4
for (int i = 1; i <= 3; ++i)
mylist2.push_back(i * 10); // mylist2: 10 20 30
it = mylist1.begin();
++it; // points to 2
mylist1.splice(it, mylist2); // mylist1: 1 10 20 30 2 3 4
// mylist2 (empty)
// "it" still points to 2 (the 5th element)
mylist2.splice(mylist2.begin(), mylist1, it);
// mylist1: 1 10 20 30 3 4
// mylist2: 2