一、List的介绍
- list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
- list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。
- list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。
- 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。
- 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)
二、List的使用
1.List的构造
构造函数( (constructor)) | 接口说明 |
---|
list() | 构造空的list | list (size_type n, const value_type& val = value_type()) | 构造的list中包含n个值为val的元素 | list (const list& x) | 拷贝构造函数 | list (InputIterator first, InputIterator last) | 用[first, last)区间中的元素构造list |
2.List迭代器的使用
函数声明 | 接口说明 |
---|
begin+end | 返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器 | rbegin+rend | 返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的 |
常见容器的迭代器
单向:++ 双向:++/– 随机:++/–/+=/-=
迭代器失效问题
前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。
void TestListIterator1()
{
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
list<int> l(array, array+sizeof(array)/sizeof(array[0]));
auto it = l.begin();
while (it != l.end())
{
其赋值
l.erase(it);
++it;
}
}
void TestListIterator()
{
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
list<int> l(array, array+sizeof(array)/sizeof(array[0]));
auto it = l.begin();
while (it != l.end())
{
l.erase(it++);
}
}
三、List的常见接口
List的插入和删除
头插和尾插
头插:void push_front (const value_type& val);
int main ()
{
std::list<int> mylist (2,100);
mylist.push_front (200);
mylist.push_front (300);
std::cout << "mylist contains:";
for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
尾插:void push_back (const value_type& val);
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;
}
头删:void pop_front();
int main ()
{
std::list<int> mylist;
mylist.push_back (100);
mylist.push_back (200);
mylist.push_back (300);
std::cout << "Popping out the elements in mylist:";
while (!mylist.empty())
{
std::cout << ' ' << mylist.front();
mylist.pop_front();
}
std::cout << "\nFinal size of mylist is " << mylist.size() << '\n';
return 0;
}
尾删:void pop_back();
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;
}
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;
}
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;
}
sort
sort可以将容器中的数据排序,默认排升序
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;
}
splice
1.将整个容器拼接到另一个容器指定迭代器的位置 2.将容器当中的某一个数据拼接到另一个容器的指定迭代器位置。 3.将容器指定迭代器区间的数据拼接到另一个容器的指定迭代器位置。
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
删除容器中特定的元素
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;
}
unique
删除容器当中连续的重复元素
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;
}
merge
将一个有序的容器合并到另一个有序的容器中。
int main ()
{
std::list<double> first, second;
first.push_back (3.1);
first.push_back (2.2);
first.push_back (2.9);
second.push_back (3.7);
second.push_back (7.1);
second.push_back (1.4);
first.sort();
second.sort();
first.merge(second);
second.push_back (2.1);
first.merge(second,mycomparison);
std::cout << "first contains:";
for (std::list<double>::iterator it=first.begin(); it!=first.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
reverse
将容器中的函数进行逆置
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;
}
|