STL详解(六) 双向链表容器list

一、List 容器简介

list是C++标准模版库(STL,Standard Template Library)中的部分内容。

list容器实质是一个双向链表,可以高效地进行插入删除元素。list不提供随机访问功能,也就是不能用下标和at()访问,当删除其中一个元素,指向其他元素的迭代器依然有效。对于任何位置的元素插入或移除,list永远是常数时间

List结构

list使用双向链表来管理元素,可以从两端发展新元素,其内部结构如下所示。

          

List能力


List的内部结构和vetor或deque截然不同,主要的区别入下:

  1. list不支持随机存取功能,可以支持首尾的直接存取,想获取其他元素,则需要遍历链表。
  2. 任何位置的删除、插入操作都非常快速,不需要移动和删除其他元素,这些操作在常数时间内完成。
  3. 安插和删除操作不会造成指向其他元素的各个pointer、reference、iterators失效
  4. list对异常操作的处理方式:要么成功,要么什么都不发生。

List所提供的成员函数区别:


list提供了不少特殊的成员函数,专门用于移动元素,和STL的通用算比较,这些成员函数的执行速度更快,主要是成员函数操作时,不需要移动元素或拷贝,仅需要调指针。
 

二、List 函数列表

构造函数
函数功能
list<T> lstTlist采用采用模板类实现,对象的默认构造形式
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)同上,此为全局函数

List的特殊变动性操作
函数功能
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);	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值