一、List 容器简介
list是C++标准模版库(STL,Standard Template Library)中的部分内容。
list容器实质是一个双向链表,可以高效地进行插入删除元素。list不提供随机访问功能,也就是不能用下标和at()访问,当删除其中一个元素,指向其他元素的迭代器依然有效。对于任何位置的元素插入或移除,list永远是常数时间
List结构
list使用双向链表来管理元素,可以从两端发展新元素,其内部结构如下所示。
List能力
List的内部结构和vetor或deque截然不同,主要的区别入下:
- list不支持随机存取功能,可以支持首尾的直接存取,想获取其他元素,则需要遍历链表。
- 任何位置的删除、插入操作都非常快速,不需要移动和删除其他元素,这些操作在常数时间内完成。
- 安插和删除操作不会造成指向其他元素的各个pointer、reference、iterators失效
- list对异常操作的处理方式:要么成功,要么什么都不发生。
List所提供的成员函数区别:
list提供了不少特殊的成员函数,专门用于移动元素,和STL的通用算比较,这些成员函数的执行速度更快,主要是成员函数操作时,不需要移动元素或拷贝,仅需要调指针。
二、List 函数列表
函数 | 功能 |
list<T> lstT | list采用采用模板类实现,对象的默认构造形式 |
list(beg,end) | 构造函数将[beg, end)区间中的元素拷贝给本身 |
list(n,elem) | 构造函数将n个elem拷贝给本身 |
list(const list &lst) | 拷贝构造函数 |
函数 | 功能 |
c.push_back(elem) | 在容器尾部加入一个元素 |
c.pop_back() | 删除容器中最后一个元素 |
c.push_front(elem) | 在容器开头插入一个元素 |
c.pop_front() | 从容器开头移除第一个元素 |
c.insert(pos,elem) | 在pos位置插elem元素的拷贝,返回新数据的位置 |
c.insert(pos,n,elem) | 在pos位置插入n个elem数据,无返回值 |
c.insert(pos,beg,end) | 在pos位置插入[beg,end)区间的数据,无返回值 |
c.clear() | 移除容器的所有数据 |
c.erase(beg,end) | 删除[beg,end)区间的数据,返回下一个数据的位置 |
c.erase(pos) | 删除pos位置的数据,返回下一个数据的位置 |
c.remove(elem) | 删除容器中所有与elem值匹配的元素 |
函数 | 功能 |
c.size() | 返回容器中元素的个数 |
c.empty() | 判断容器是否为空 |
resize(num) | 重新指定容器的长度为num,变长则用默认值填充新位置;变短删除超出元素 |
resize(num, elem) | 重新指定容器的长度为num,变长则用elem填充新位置;变短删除超出元素 |
c1 == c2 | 判断c1 是否等于c2 |
c1 != c2 | 判断c1是否不等于c2 |
c1 < c2 | 判断c1 是否小于c2 |
c1 > c2 | 判断c1 是否大于c2 |
c1 <= c2 | 判断c1是否小于等于c2 |
c1 >= c2 | 判断c1是否大于等于c2 |
函数 | 功能 |
c1 = c2 | 将c2的全部元素赋值给c1 |
c.assign(n, elem) | 复制n个elem,复制给c |
c.assign(beg, end) | 将区间[beg;end)内的元素赋值给c |
c1.swap(c2) | 将c1和c2元素互换 |
swap(c1,c2) | 同上,此为全局函数 |
函数 | 功能 |
reverse() | 反转链表:1,2,3,反转后为3,2,1 |
sort() | sort为list的成员函数,而不是STL算法 |
c.sort(op) | 以op()为准则,对所有元素排序 |
c.unique() | 如果存在若干相邻而数值相等的元素,就移除重复元素,只留下一个 |
c.unique(op) | 如果存在若干相邻元素,都使op()的结果为ture,则移除重复元素,只留下一个。 |
c1.splice(pos, c2) | 将c2内的所有元素转移到c1之内,迭代器pos之前 |
c1.splice(pos, c2, c2pos) | 将c2内的c2pos所指元素转移到c1之内的pos所指位置上(c1,c2可相同) |
c1.splice(pos, c2, c2beg,c2end) | 将c2内的[c2beg,c2end)区间内所有元素转移到c1内的pos之前(c1,c2可相同) |
c1.merge(c2) | 假设c1和c2容器都包含已序(相同的排序方式)元素,将c2的全部元素转移到c1,并保证合并后的list还是已序。 |
c1.merge(c2,op) | 假设c1和c2容器都包含op()原则下的已序(相同的排序方式)元素,将c2的全部元素转移到c1,并保证合并后的list在op()原则仍是已序。 |
三、List 容器成员函数详解
3.1、构造函数
list<int> c0; //空链表
list<int> c1(3); //建一个含三个默认值是0的元素的链表
list<int> c2(5,2); //建一个含五个元素的链表,值都是2
list<int> c4(c2); //建一个c2的copy链表
list<int> c5(c1.begin(),c1.end()); c5含c1一个区域的元素[_First, _Last)。
3.2、数据遍历函数(不能用下标和at()访问)
3.2.1、迭代器访问
c.begin() 返回指向链表c中第一个元素的迭代器。
c.end() 返回指向链表c中最后一个元素之后的迭代器。
c.rbegin() 返回逆向链表c中的第一个元素,即c链表的最后一个数据。
c.rend() 返回逆向链表c中的最后一个元素的下一个位置,即c链表的第一个数据再往前的位置。
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1;
for(int i=1;i<=5;i++) a1.push_back(i);
list<int>::iterator it;
for(it = a1.begin();it!=a1.end();it++)
cout << *it << "\t";
cout << endl;
}
结果为:
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1;
for(int i=1;i<=5;i++) a1.push_back(i);
list<int>::reverse_iterator it;
for(it = a1.rbegin();it!=a1.rend();it++)
cout << *it << "\t";
cout << endl;
}
结果为:
3.2.2、front 与 back
c.front() 返回链表c的第一个元素。
c.back() 返回链表c的最后一个元素。
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1;
for(int i=1;i<=5;i++) a1.push_back(i);
if(!a1.empty())
{ cout << "the first number is:" << a1.front() << endl;
cout << "the last number is:" << a1.back() << endl;
}
}
3.3、大小操作
3.3.1 c.empty() 判断链表c中是否为空。
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1;
for(int i=1;i<=5;i++) a1.push_back(i);
if(!a1.empty())
cout << "a1 is not empty" << endl;
else
cout << " a1 is empty" << endl;
}
结果为:
3.3.2 c.size() 返回链表c中实际元素的个数。
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1;
for(int i=1;i<=5;i++) a1.push_back(i);
cout << a1.size() << endl;
}
结果为:
3.3.3 c.max_size() 返回链表c中可能容纳的最大元素数量。
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1;
for(int i=1;i<=5;i++) a1.push_back(i);
cout << a1.max_size() << endl;
}
结果为:
3.3.4resize(n) 与resize(n,num)
resize(n) 重新定义链表的长度,超出原始长度部分用0代替,小于原始部分删除。
resize(n,num) 从新定义链表的长度,超出原始长度部分用num代替。
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1;
for(int i=1;i<=5;i++) a1.push_back(i);
a1.resize(8);
list<int>::iterator it;
cout << "resize(n):";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
a1.resize(10, 10);
cout << "resize(n,num):";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
}
结果为:
3.4、赋值
3.4.1 operator = 重载赋值运算符。
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1,a2;
for(int i=1;i<=5;i++) a1.push_back(i);
a2 = a1;
list<int>::iterator it;
for(it = a2.begin();it!=a2.end();it++) cout << *it << endl;
}
结果为:
3.4.2 assign(n,num) 与assign(beg,end)
c.assign(n,num) 将n个num拷贝赋值给链表c。
c.assign(beg,end) 将[beg,end)区间的元素拷贝赋值给链表c。
#include<bits/stdc++.h>
using namespace std;
int main()
{ int a[5] = {1,2,3,4,5};
list<int> a1;
list<int>::iterator it;
a1.assign(2,10);
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
a1.assign(a,a+5);
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
}
结果为:
3.4.3 swap()交换
c1.swap(c2); 将c1和c2交换。
swap(c1,c2); 同上。
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1,a2,a3;
for(int i=1;i<=5;i++) a1.push_back(i);
a2.swap(a1);
list<int>::iterator it;
cout << "a2.swap(a1):";
for(it = a2.begin();it!=a2.end();it++)
cout << *it << " ";
cout << endl;
swap(a3,a2);
cout << "swap(a3,a2):";
for(it = a3.begin();it!=a3.end();it++)
cout << *it << " ";
}
结果为:
3.5、插入与删除
3.5.1 clear() 清除链表c中的所有元素。
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1;
for(int i=1;i<=5;i++) a1.push_back(i);
list<int>::iterator it;
cout << "clear before:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << "\t";
cout << endl;
a1.clear();
cout << "clear after:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << "\t";
cout << endl;
}
结果为:
3.5.2 insert() 插入
c.insert(pos,num) 在pos位置插入元素num。
c.insert(pos,n,num) 在pos位置插入n个元素num。
c.insert(pos,beg,end) 在pos位置插入区间为[beg,end)的元素。
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1;
for(int i=1;i<=5;i++) a1.push_back(i);
list<int>::iterator it;
cout << "insert before:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
a1.insert(a1.begin(),0);
cout << "insert(pos,num) after:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
a1.insert(a1.begin(),2,88);
cout << "insert(pos,n,num) after:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
int arr[5] = {11,22,33,44,55};
a1.insert(a1.begin(),arr,arr+3);
cout << "insert(pos,beg,end) after:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
}
结果为:
3.5.3 erase 删除
c.erase(pos) 删除pos位置的元素,返回下一个数据的位置。
c.erase(beg,end) 删除[beg,end)区间的数据,返回下一个数据的位置
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1;
for(int i=1;i<=5;i++) a1.push_back(i);
list<int>::iterator it;
cout << "erase before:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
a1.erase(a1.begin());
cout << "erase after:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
}
结果为:
3.5.4 首尾加入与删除元素
c.push_back(num) 在末尾增加一个元素。
c.pop_back() 删除末尾的元素。
c.push_front(num) 在开始位置增加一个元素。
c.pop_front() 删除第一个元素。
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> a1;
for(int i=1;i<=5;i++) a1.push_back(i);
a1.push_back(10);
list<int>::iterator it;
cout << "push_back:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
a1.pop_back();
cout << "pop_back:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
a1.push_front(20);
cout << "push_front:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
a1.pop_front();
cout << "pop_front:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
}
结果为:
3.5.4 合并并排序(排序的前提是2个链表必须是有序的)
c1.merge(c2) 合并2个有序的链表并使之有序,从新放到c1里,释放c2。
c1.merge(c2,comp) 合并2个有序的链表并使之按照自定义规则排序之后从新放到c1中,释放c2。
#include<bits/stdc++.h>
using namespace std;
int main()
{ int a1[]={4,5,7},a2[]={1,2,6,9};
list<int> L1(a1,a1+3),L2(a2,a2+4);
L1.merge(L2);
list<int>::iterator it;
cout << "L1.merge(L2), L1:";
for(it = L1.begin();it!=L1.end();it++)
cout << *it << " ";
cout<<endl;
cout << "L1.merge(L2), L2:";
for(it = L2.begin();it!=L2.end();it++)
cout << *it << " ";
cout << endl;
L2.merge(L1,[](int n1,int n2){return n1>n2;});
cout << "L2.merge(L1,comp):";
for(it = L2.begin();it!=L2.end();it++)
cout << *it << " ";
cout << endl;
}
结果为:
注意:1)merge()是将两个有序的链表合并成另一个有序的链表,如果有一个链表不是有序的那么在执行代码时会报错:说链表不是有序的。
2)还有,两个链表中的内容排序顺序与合并时采用的排序顺序必须一致,如果不一致,也会报错,说链表不是有序的。如想要降序合并两个链表,那么合并前的两个链表也必须是按降序排列的。
3)另外,当执行完merge()后,右边的链表将变为空。
3.5.5 连接链表
c1.splice(c1.beg,c2) 将c2连接在c1的beg位置,释放c2
#include<bits/stdc++.h>
using namespace std;
int main()
{ int a1[]={1,2,3},a2[]={4,5,6};
list<int> L1(a1,a1+3),L2(a2,a2+3);
L1.splice(L1.begin(), L2);
list<int>::iterator it;
cout << "L1.merge(a2):";
for(it = L1.begin();it!=L1.end();it++)
cout << *it << " ";
cout << endl;
}
结果为:
c1.splice(c1.beg,c2,c2.beg) 将c2的beg位置的元素连接到c1的beg位置,并且在c2中施放掉beg位置的元素
#include<bits/stdc++.h>
using namespace std;
int main()
{ int a1[]={1,2,3},a2[]={4,5,6};
list<int> L1(a1,a1+3),L2(a2,a2+3);
L1.splice(L1.begin(), L2,++L2.begin());
list<int>::iterator it;
cout << "L1.merge(L2):";
for(it = L1.begin();it!=L1.end();it++)
cout << *it << " ";
cout << endl;
}
结果为:
c1.splice(c1.beg,c2,c2.beg,c2.end) 将c2的[beg,end)位置的元素连接到c1的beg位置并且释放c2的[beg,end)位置的元素
1#include<bits/stdc++.h>
using namespace std;
int main()
{ int a1[]={1,2,3},a2[]={4,5,6};
list<int> L1(a1,a1+3),L2(a2,a2+3);
L1.splice(L1.begin(),L2,L2.begin(),L2.end());
list<int>::iterator it;
cout << "L1.merge(a2):";
for(it = L1.begin();it!=L1.end();it++)
{ cout << *it << " ";
}
cout << endl;
return 0;
}
结果为:
3.5.6 删除链表元素
remove(num) 删除链表中匹配num的元素。
#include<bits/stdc++.h>
using namespace std;
int main()
{ int a[]={1,2,3,4,5};
list<int> a1(a,a+5);
a1.remove(3);
list<int>::iterator it;
cout << "remove():";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
}
结果为:
remove_if(comp) 删除条件满足的元素,参数为自定义的回调函数。
#include<bits/stdc++.h>
using namespace std;
int main()
{ int a[]={1,2,3,4,5};
list<int> a1(a,a+5);
a1.remove_if([](int n){return n<3;});
list<int>::iterator it;
cout << "remove_if():";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
}
结果为:
3.5.7 reverse() 反转链表
#include<bits/stdc++.h>
using namespace std;
int main()
{ int a[]={1,2,3,4,5};
list<int> a1(a,a+5);
a1.reverse();
list<int>::iterator it;
cout << "reverse:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
}
结果为:
3.5.8 unique() 删除相邻的元素
如果存在若干相邻而数值相等的元素,就移除重复元素,只留下一个
#include<bits/stdc++.h>
using namespace std;
int main()
{ int a[]={1,1,3,3,5};
list<int> a1(a,a+5);
a1.unique();
list<int>::iterator it;
cout << "unique:";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
return 0;
}
结果为:
3.5.9 c.sort() 将链表排序,默认升序
c.sort(comp) 自定义回调函数实现自定义排序
STL 中的算法 sort 可以用来对 vector 和 deque 排序,它需要随机访问迭代器的支持。因为 list 不支持随机访问迭代器,所以不能用算法 sort 对 list 容器排序。因此,list 容器引入了 sort 成员函数以完成排序。
#include<bits/stdc++.h>
using namespace std;
int main()
{ int a[]={1,3,2,5,4};
list<int> a1(a,a+5);
a1.sort();
list<int>::iterator it;
cout << "sort():";
for(it = a1.begin();it!=a1.end();it++)
cout << *it << " ";
cout << endl;
//a1.sort([](int n1,int n2){return n1>n2;});
//cout << "sort(function point):";
//for(it = a1.begin();it!=a1.end();it++)
//cout << *it << " ";
cout << endl;
}
四、应用举例:
1、用 list 解决约瑟夫问题。
约瑟夫问题是:有 n 只猴子,按顺时针方向围成一圈选大王(编号为 1~n),从第 1 号开始报数,一直数到 m,数到 m 的猴子退到圈外,剩下的猴子再接着从 1 开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王。编程求输入 n、m 后,输出最后猴王的编号。
输入数据:每行是用空格分开的两个整数,第一个是 n,第二个是 m(0<m, n<=1 000 000)。最后一行是:
0 0
输出要求:对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号。
输入样例:
6 2
12 4
8 3
0 0
输出样例:
5
1
7
示例程序如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{ list<int> monkeys;
int n, m;
while (true)
{ cin >> n >> m;
if (n == 0 && m == 0) break;
monkeys.clear(); //清空list容器
for (int i = 1; i <= n; ++i) //将猴子的编号放入list
monkeys.push_back(i);
list<int>::iterator it = monkeys.begin();
while (monkeys.size() > 1) //只要还有不止一只猴子,就要找一只猴子让其出列
{ for (int i = 1; i < m; ++i)
{ ++it; //报数
if (it == monkeys.end())
it = monkeys.begin();
}
it = monkeys.erase(it); //删除元素后,迭代器失效,
//要重新让迭代器指向被删元素的后面
if (it == monkeys.end())
it = monkeys.begin();
}
cout << monkeys.front() << endl; //front返回第一个元素的引用
}
return 0;
}
erase 成员函数返回被删除元素后面那个元素的迭代器。如果被删除的是最后一个元素,则返回 end()。
这个程序也可以用 vector 实现,但是执行速度要慢很多。因为 vector 的 erase 操作牵涉元素的移动,不能在常数时间内完成,所花费的时间和容器中的元素个数有关;而 list 的 erase 操作只是修改几个指针而已,可以在常数时间内完成。当 n 很大(数十万)时,两种写法在速度上会有明显区别。
2、描述
写一个程序完成以下命令:
new id ——新建一个指定编号为id的序列(id<10000)
add id num——向编号为id的序列加入整数num
merge id1 id2——合并序列id1和id2中的数,并将id2清空
unique id——去掉序列id中重复的元素
out id ——从小到大输出编号为id的序列中的元素,以空格隔开
输入第一行一个数n,表示有多少个命令( n<=200000)。以后n行每行一个命令。输出按题目要求输出。样例输入
16
new 1
new 2
add 1 1
add 1 2
add 1 3
add 2 1
add 2 2
add 2 3
add 2 4
out 1
out 2
merge 1 2
out 1
out 2
unique 1
out 1
样例输出
1 2 3
1 2 3 4
1 1 2 2 3 3 4
1 2 3 4
示例程序如下:
#include<bits/stdc++.h>
using namespace std;
list<int> all[10005];
int main()
{ int n;
cin >> n;
for (int i = 1; i <= n; i++)
{ string line;
cin >> line;
if (line == "new")
{ int id;
cin >> id;
}
if (line == "add")
{ int id, num;
cin >> id >> num;
all[id].push_back(num);
all[id].sort();
}
if (line == "out")
{ int id;
cin >> id;
list<int>::iterator p;
p = all[id].begin();
if (p != all[id].end())
{ cout << *p++;
for (; p != all[id].end(); p++)
cout << " " << *p;
}
cout << endl;
}
if (line == "merge")
{ int a, b;
cin >> a >> b;
all[a].merge(all[b]);
all[a].sort();
}
if (line == "unique")
{ int id;
cin >> id;
all[id].unique();
}
}
return 0;
}
3:删除数组中的元素(链表)
描述
给定N个整数,将这些整数中与M相等的删除
假定给出的整数序列为:1,3,3,0,-3,5,6,8,3,10,22,-1,3,5,11,20,100,3,9,3
应该将其放在一个链表中,链表长度为20
要删除的数是3,删除以后,链表中只剩14个元素:1 0 -3 5 6 8 10 22 -1 5 11 20 100 9
输入
输入包含3行:
第一行是一个整数n(1 <= n <= 200000),代表数组中元素的个数。
第二行包含n个整数,代表数组中的n个元素。每个整数之间用空格分隔;每个整数的取值在32位有符号整数范围以内。
第三行是一个整数k,代表待删除元素的值(k的取值也在32位有符号整数范围内)。
输出
输出只有1行:
将数组内所有待删除元素删除以后,输出数组内的剩余元素的值,每个整数之间用空格分隔。
样例输入
20
1 3 3 0 -3 5 6 8 3 10 22 -1 3 5 11 20 100 3 9 3
3
例输出
1 0 -3 5 6 8 10 22 -1 5 11 20 100 9
4、6379:统计学生信息
描述
利用动态链表记录从标准输入输入的学生信息(学号、姓名、性别、年龄、得分、地址)
其中,学号长度不超过20, 姓名长度不超过40, 性别长度为1, 地址长度不超过40
输入
包括若干行,每一行都是一个学生的信息,如:
00630018 zhouyan m 20 10.0 28#460
输入的最后以"end"结束
输出
将输入的内容倒序输出
每行一条记录,按照
学号 姓名 性别 年龄 得分 地址
的格式输出
样例输入
00630018 zhouyan m 20 10 28#4600
0063001 zhouyn f 21 100 28#460000
0063008 zhoyan f 20 1000 28#460000
0063018 zhouan m 21 10000 28#4600000
00613018 zhuyan m 20 100 28#4600
00160018 zouyan f 21 100 28#4600
01030018 houyan m 20 10 28#4600
0630018 zuyan m 21 100 28#4600
10630018 zouan m 20 10 28#46000
end
样例输出
10630018 zouan m 20 10 28#46000
0630018 zuyan m 21 100 28#4600
01030018 houyan m 20 10 28#4600
00160018 zouyan f 21 100 28#4600
00613018 zhuyan m 20 100 28#4600
0063018 zhouan m 21 10000 28#4600000
0063008 zhoyan f 20 1000 28#460000
0063001 zhouyn f 21 100 28#460000
00630018 zhouyan m 20 10 28#4600
#include<bits/stdc++.h>
using namespace std;
list<string> l;
int main() {
string line;
while(getline(cin, line) && line != "end")
l.push_back(line);//如果这里改为push_front,则下面不用这么麻烦
for(list::reverse_iterator it = l.rbegin(); it!=l.rend(); ++it)
cout << *it << endl;
}
#include<bits/stdc++.h>
using namespace std;
struct stu
{ char num[25], name[45], sex, scr[45];
int age;
char addr[45];
friend bool operator<(const stu &a,const stu &b){
return a.name<b.name; //按value从大到小排列
}
} p;
void fun(stu &d){
cout <<d.num << " "
<<d.name<< " "
<<d.sex << " "
<<d.age << " "
<<d.scr << " "
<<d.addr<< "\n"; //"\n"比endl效率更高
}
int main()
{ list<stu> ls;
int i;
for(i=1;i<=5;i++)
{ cin>>p.num>>p.name>>p.sex>>p.age>>p.scr>>p.addr;
ls.push_front(p);
}
ls.sort();
list <stu>::iterator it=ls.begin();
for(it = ls.begin();it!=ls.end();it++)
fun(*it);
}