一. list介绍
list文档介绍
1). list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。 2). list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。 3). list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝后迭代,已让其更简单高效。 4).与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。 5). 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)
二. list使用
constructor
1).构造一个空容器
list<int> lt;
2).构造一个含有n个值为val的容器
list<int> lt(10,5);
3).拷贝构造
list<int> lt2(lt);
4). 迭代器区间构造
int a[] = { 16,2,77,29 };
list<int> lt2(a,a + 4);
print(lt2);
sort(a,a + 4);
sort(a, a + 4, greater<int>());
sort(lt.begin(),lt.end());
list迭代器是双向迭代器,不支持 - 操作,因此报错
这里顺便介绍一下迭代器的类型 : 单向迭代器 : 只能向后依次遍历(只支持++操作) (如 forward_list) 双向迭代器 : 可以向前向后依次遍历(支持++和–操作) (如 list) 随机迭代器 : 可以向前向后随机遍历(支持++ /- - / + / - / += / -= 操作) (如 vector/string)
iterator
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> lt(10, 5);
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
cout << *it << " ";
it++;
}
cout << endl;
list<int>::reverse_iterator rit = lt.rbegin();
while (rit != lt.rend())
{
cout << *rit << " ";
rit++;
}
cout << endl;
return 0;
}
capacity
empty
判断容器是否为空
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> lt;
cout << lt.empty() << endl;
return 0;
}
size
获取容器中的元素个数
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
cout << lt.size() << endl;
return 0;
}
Element access
front/back
front函数用于获取list容器当中的第一个元素的引用,back函数用于获取list容器当中的最后一个元素的引用
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
cout << lt.front() << endl;
cout << lt.back() << endl;
return 0;
}
Modifiers
assign
将新内容赋值给list容器,替换其当前内容,并相应地修改其大小
1). 将n个值为val的数据分配给容器。 2). 将所给迭代器区间当中的内容分配给容器。
#include <iostream>
#include <list>
using namespace std;
int main ()
{
list<int> first;
list<int> second;
first.assign (7,100);
second.assign (first.begin(),first.end());
int myints[]={1776,7,4};
first.assign (myints,myints+3);
cout << "Size of first: " << int (first.size()) << endl;
cout << "Size of second: " << int (second.size()) << endl;
return 0;
}
push_front/pop_front
头插,头删容器中的数据
#include <iostream>
#include <list>
using namespace std;
int main ()
{
list<int> mylist (2,100);
mylist.push_front (200);
mylist.push_front (300);
cout << "mylist contains:";
for (list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
cout << ' ' << *it;
cout << endl;
return 0;
}
#include <iostream>
#include <list>
using namespace std;
int main ()
{
list<int> mylist;
mylist.push_back (100);
mylist.push_back (200);
mylist.push_back (300);
cout << "Popping out the elements in mylist:";
while (!mylist.empty())
{
cout << ' ' << mylist.front();
mylist.pop_front();
}
cout << "\nFinal size of mylist is " << mylist.size() << endl;
return 0;
}
push_back/pop_back
尾插,尾删容器中的数据
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist;
int myint;
std::cout << "Please enter some integers (enter 0 to end):\n";
do {
std::cin >> myint;
mylist.push_back (myint);
} while (myint);
std::cout << "mylist stores " << mylist.size() << " numbers.\n";
return 0;
}
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist;
int sum (0);
mylist.push_back (100);
mylist.push_back (200);
mylist.push_back (300);
while (!mylist.empty())
{
sum+=mylist.back();
mylist.pop_back();
}
std::cout << "The elements of mylist summed " << sum << '\n';
return 0;
}
insert
1).在指定迭代器位置插入一个数。 2). 在指定迭代器位置插入n个值为val的数。 3).在指定迭代器位置插入一段迭代器区间(左闭右开)。
#include <iostream>
#include <list>
#include <vector>
int main ()
{
std::list<int> mylist;
std::list<int>::iterator it;
for (int i=1; i<=5; ++i) mylist.push_back(i);
it = mylist.begin();
++it;
mylist.insert (it,10);
mylist.insert (it,2,20);
--it;
std::vector<int> myvector (2,30);
mylist.insert (it,myvector.begin(),myvector.end());
std::cout << "mylist contains:";
for (it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
#include <iostream>
#include <list>
int main()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
list<int>::iterator pos = find(lt.begin(),lt.end(),3);
lt.insert(pos,30);
print(lt);
cout << *pos << endl;
}
insert 不会导致迭代器失效,因为链表的插入并不会影响 it/pos 所指向的位置
erase
1).删除指定迭代器位置的元素。 2). 删除指定迭代器区间(左闭右开)的所有元素。
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist;
std::list<int>::iterator it1,it2;
for (int i=1; i<10; ++i) mylist.push_back(i*10);
it1 = it2 = mylist.begin();
advance (it2,6);
++it1;
it1 = mylist.erase (it1);
it2 = mylist.erase (it2);
++it1;
--it2;
mylist.erase (it1,it2);
std::cout << "mylist contains:";
for (it1=mylist.begin(); it1!=mylist.end(); ++it1)
std::cout << ' ' << *it1;
std::cout << '\n';
return 0;
}
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
list<int>::iterator pos = find(lt.begin(), lt.end(), 3);
lt.erase(pos);
print(lt);
cout << *pos << endl;
}
erase 会导致迭代器失效,因为链表的删除会使 pos 所指向的位置被释放,从而 pos 成为野指针
swap
swap用于交换两个容器的内容
#include <iostream>
#include <list>
int main ()
{
std::list<int> first (3,100);
std::list<int> second (5,200);
first.swap(second);
std::cout << "first contains:";
for (std::list<int>::iterator it=first.begin(); it!=first.end(); it++)
std::cout << ' ' << *it;
std::cout << '\n';
std::cout << "second contains:";
for (std::list<int>::iterator it=second.begin(); it!=second.end(); it++)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
resize
1). 若 n 小于当前容器的 size ,size 减少到 n 2). 若 n 大于当前容器的 size,尾插入数据直到 n,值用 val 来填充
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist;
for (int i=1; i<10; ++i) mylist.push_back(i);
mylist.resize(5);
mylist.resize(8,100);
mylist.resize(12);
std::cout << "mylist contains:";
for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
clear
清空容器,使容器的 size 成为 0
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist;
std::list<int>::iterator it;
mylist.push_back (100);
mylist.push_back (200);
mylist.push_back (300);
std::cout << "mylist contains:";
for (it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
mylist.clear();
mylist.push_back (1101);
mylist.push_back (2202);
std::cout << "mylist contains:";
for (it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
operations
splice
splice函数用于两个list容器数据之间的转移,其有三种拼接方式:
1).将整个容器拼接到另一个容器的指定迭代器位置。 2).将容器当中的某一个数据拼接到另一个容器的指定迭代器位置。 3).将容器指定迭代器区间的数据拼接到另一个容器的指定迭代器位置。
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist1, mylist2;
std::list<int>::iterator it;
for (int i=1; i<=4; ++i)
mylist1.push_back(i);
for (int i=1; i<=3; ++i)
mylist2.push_back(i*10);
it = mylist1.begin();
++it;
mylist1.splice (it, mylist2);
mylist2.splice (mylist2.begin(),mylist1, it);
it = mylist1.begin();
std::advance(it,3);
mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
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;
}
remove
remove函数用于删除容器当中被指定的元素,和erase不同,erase是删除迭代器位置的值
#include <iostream>
#include <list>
int main ()
{
int myints[] = {17,89,7,14};
std::list<int> mylist (myints,myints+4);
mylist.remove(89);
std::cout << "mylist contains:";
for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
remove_if
remove_if函数用于删除容器当中满足条件的元素。
#include <iostream>
#include <list>
bool single_digit (const int& value) { return (value<10); }
struct is_odd {
bool operator() (const int& value) { return (value%2)==1; }
};
int main ()
{
int myints[]= {15,36,7,17,20,39,4,1};
std::list<int> mylist (myints,myints+8);
mylist.remove_if (single_digit);
mylist.remove_if (is_odd());
std::cout << "mylist contains:";
for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
unique
unique函数用于删除容器当中连续的重复元素(配合sort使用)。
#include <iostream>
#include <cmath>
#include <list>
bool same_integral_part (double first, double second)
{ return ( int(first)==int(second) ); }
struct is_near {
bool operator() (double first, double second)
{ return (fabs(first-second)<5.0); }
};
int main ()
{
double mydoubles[]={ 12.15, 2.72, 73.0, 12.77, 3.14,
12.77, 73.35, 72.25, 15.3, 72.25 };
std::list<double> mylist (mydoubles,mydoubles+10);
mylist.sort();
mylist.unique();
mylist.unique (same_integral_part);
mylist.unique (is_near());
std::cout << "mylist contains:";
for (std::list<double>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
sort
sort 默认将容器中的数据排成升序,排降序可以用 greater<>
#include <iostream>
#include <list>
#include <string>
#include <cctype>
bool compare_nocase (const std::string& first, const std::string& second)
{
unsigned int i=0;
while ( (i<first.length()) && (i<second.length()) )
{
if (tolower(first[i])<tolower(second[i])) return true;
else if (tolower(first[i])>tolower(second[i])) return false;
++i;
}
return ( first.length() < second.length() );
}
int main ()
{
std::list<std::string> mylist;
std::list<std::string>::iterator it;
mylist.push_back ("one");
mylist.push_back ("two");
mylist.push_back ("Three");
mylist.sort();
std::cout << "mylist contains:";
for (it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
mylist.sort(compare_nocase);
std::cout << "mylist contains:";
for (it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
reverse
reverse函数用于将容器当中元素的位置进行逆置。
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist;
for (int i=1; i<10; ++i) mylist.push_back(i);
mylist.reverse();
std::cout << "mylist contains:";
for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
|