#include<cstdio>
#include<list>
using namespace std;
const int maxn=3e5+5;
list<int>li[maxn]; //创建空list
int main()
{
int ci,n,q,m,s,v,t,i;
scanf("%d",&ci);
while(ci--)
{
scanf("%d%d",&n,&q);
for( i=1;i<=n;i++) //初始化
li[i].clear();
while(q--)
{
scanf("%d",&m);
if(m==1)
{
scanf("%d%d",&s,&v);
li[s].push_back(v); //在list末尾添加一个元素
}
else if(m==2)
{
scanf("%d",&s);
if(li[s].empty()) //如果是空,返回true
printf("EMPTY\n");
else
{
printf("%d\n",li[s].back()); //返回最后一个元素
li[s].pop_back(); //删除最后一个元素
}
}
else
{
scanf("%d%d",&s,&t);
li[s].splice(li[s].end(),li[t]); //合并两个list
}
}
}
return 0;
}
List是stl实现的双向链表,与向量vector相比,它允许快速的插入和删除,但是随机访问比较慢。使用时需要
添加头文件 #include<list>
List 定义和初始化:
list <int>lst 1;//创建空list
list<int>lst2(5);//创建含有5个元素的list
list<int>lst3(3,2);//创建含有3个元素的list
list<int>lst4(lst2);//使用lst2初始化lst4
list<int>lst5(lst2.begin(),lst2.end());//同lst4
List常用操作函数:
Lst1.assign() //给list赋值
Lst1.back()//返回最后一个元素
Lst1.begin()//返回指向第一个元素的迭代器
Lst1.clear()//删除所有元素
Lst1.empty()//如果list是空的则返回true
Lst1.end()// 返回末尾的迭代器
Lst1.erase()//删除一个元素
Lst1.front() 返回第一个元素
Lst1.get_allocator() //返回list的配置器
Lst1.insert() //插入一个元素到list中
Lst1.max_size()// 返回list能容纳的最大元素数量
Lst1.merge() //合并两个list
Lst1.pop_back()// 删除最后一个元素
Lst1.pop_front() //删除第一个元素
Lst1.push_back() //在list的末尾添加一个元素
Lst1.push_front() //在list的头部添加一个元素
Lst1.rbegin() //返回指向第一个元素的逆向迭代器
Lst1.remove() //从list删除元素
Lst1.remove_if()// 按指定条件删除元素
Lst1.rend() //指向list末尾的逆向迭代器
Lst1.resize() //改变list的大小
Lst1.reverse() //把list的元素倒转
Lst1.size() //返回list中的元素个数
Lst1.sort() //给list排序
Lst1.splice() //合并两个list
Lst1.swap() //交换两个list
Lst1.unique() //删除list中重复的元素
list 的splice函数主要是用来合并两个list。
splice是list中特有的拼接方法。splice实现了不需要拷贝的list合并,即可以在常数时间内从list的一个区域拼接到另一个list的一个区域。也就是说splice是一个常数时间的函数
// splicing lists
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist1, mylist2;
std::list<int>::iterator it;
// set some initial values:
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)
//此处的it由于是指向的mylist1,splice后,此迭代器依然存在于
//mylist1中,故而不失效,而后面的splice,由于it指向的地址被插入到
//mylist2中,而使迭代器it失效
mylist2.splice (mylist2.begin(),mylist1, it); //把mylist1里it指向的内容剪切到mylest2.begin()后边
// mylist1: 1 10 20 30 3 4
// mylist2: 2
// "it" is now invalid.
it = mylist1.begin();
std::advance(it,3); // "it" points now to 30
//advance:it本来指向1,往后推三个,现在指向30
mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end()); //把mylist1里it到mylis1.end()的内容剪切到mylist1.end()后面
// mylist1: 30 3 4 1 10 20
//注意此处mylist前后交换了,这可以用作list形如循环移位的操作
std::cout << "mylist1 contains:";
for (it=mylist1.begin(); it!=mylist1.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
std::cout << "mylist2 contains:";
for (it=mylist2.begin(); it!=mylist2.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}