STL与泛型编程<四>:List

List使用一个双向链表来管理元素。
STL与泛型编程<四>:List_第1张图片

List的能力

List的内部结构与vector和deque截然不同,因此区别也很显著,如下
1. List不支持随机存取。所以在List遍历是很缓慢的行为
2. 任何位置安插与删除元素非常快
3. 安插和删除元素并不会造成指向其他元素的各个pointer,reference,iterator失效
List提供的成员函数也可以看出来它和vector以及deque的不同
1. 由于不能随机存取,List既不提供下标符,也不提供at()。
2. List并未提供容量/空间分配等操作符,因为并无必要。
3. List提供了不少特殊的成员函数,专门用于移动元素。较之同名的STL通用算法,这些函数执行更快,因为它们无需拷贝或移动,只需调整若干指针即可

List的操作函数

  • 生成,复制,销毁
    STL与泛型编程<四>:List_第2张图片
  • 非变动性操作
  • 赋值操作
  • 元素存取
    STL与泛型编程<四>:List_第3张图片
    List不支持随机操作,只有front和back能够直接存取元素,这些函数并不检查空,所以调用者必须确保容器至少含有一个元素,如
list<int> col;
if (!col.empty())
{
    cout << col.back();
}
  • 迭代器相关函数
    STL与泛型编程<四>:List_第4张图片
    只有运用迭代器才能存取list中的各个元素,且由于list不能随机存取,这些迭代器只是双向迭代器。所以凡是用到随机迭代器的算法,你都不能调用。
  • 元素的安插和移除
    STL与泛型编程<四>:List_第5张图片
    下面看例子
#include <iostream>
#include <iterator>
#include <list>
#include <algorithm>

using namespace std;

int main(void)
{
    list<int> col;
    col.push_back(1);
    col.push_back(2);
    col.push_back(3);
    copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); // 1 2 3
    cout << endl;

    col.insert(col.begin(),0);
    copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); // 0 1 2 3
    cout << endl;

    col.insert(col.begin(),col.begin(),col.end());
    copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); // 0 1 2 3 0 1 2 3
    cout << endl;

    col.remove(0);
    copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); // 1 2 3 1 2 3
    cout << endl;

    col.erase(col.begin());
    copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); //2 3 1 2 3 
    cout << endl;

    col.clear();
    copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); //不打印 
    return 0;   
} 
  • splice函数
    List的好处就是不论任何位置,元素的安插和移除都只需要常数时间,如果你需要将容器A中的若干元素转放到容器B中,那么就好办了,只需重新定义一些指针就好了。为此list提供了特殊的变动性函数用于改变元素和区间的次序,或是用来重新串连。
    STL与泛型编程<四>:List_第6张图片

    例子
#include <iostream>
#include <iterator>
#include <list>
#include <algorithm>

using namespace std;

int main(void)
{
    int arr1[] = {1,2,2,3,4};
    list<int> col1(arr1,arr1+sizeof(arr1)/sizeof(arr1[0]));
    copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," "));  // 1 2 2 3 4
    cout << endl;

    col1.unique();
    copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," "));  // 1 2 3 4
    cout << endl;

    int arr2[] = {5,6};
    list<int> col2(arr2,arr2+2);
    copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," "));  //5,6
    cout << endl;

    col1.splice(col1.begin(),col2); 
    copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," "));  // 5 6 1 2 3 4
    cout << endl;

    copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); //不打印任何,因为col2的元素已被移到col1中去了 
    cout << endl;

    col1.sort();
    copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); // 1 2 3 4 5 6
    cout << endl;

    col1.reverse();
    copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); // 6 5 4 3 2 1
    cout << endl;

    return 0;   
} 

再看一个关于merge()的例子

#include <iostream>
#include <iterator>
#include <list>
#include <algorithm>

using namespace std;

int main(void)
{
    list<int> col1;
    col1.push_back(1);
    col1.push_back(12);
    col1.push_back(30);
    copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); // 1 2 3
    cout << endl;

    list<int> col2;
    col2.push_back(4);
    col2.push_back(5);
    col2.push_back(6);
    copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); // 4 5 6
    cout << endl;
    list<int> col3(col2);

    col1.merge(col2);
    copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); // 1 4 5 6 12 30
    cout << endl;

    col2.reverse();
    copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); //不打印 
    cout << endl;

    col3.reverse();
    col1.merge(col3);
    copy(col1.begin(),col1.end(),ostream_iterator<int>(cout," ")); //没有排序 

    return 0;   
} 

关于list的merge()函数还没有细研究,反正记住使用这个成员函数是有条件的,必须是有序元素。

总结

可以看出list比一般容器共通操作多出的函数如下

assign(n,elem);
assign(beg,end);
remove(val);
remove_if(op);
resize(num);
resize(num,elem);
unique();
unique(op);
c1.splice(pos,c2); 
c1.splice(pos,c2,c2pos);
c1.splice(pos,c2,c2beg,c2end);
sort();
merge();
reverse();
  1. 首先可以看出list比一般容器多了许多与拼接(splice)有关的成员函数,当然是因为其实作版本一般是双向链表,所以很多操作只需要移动指针就可以,效率很高

你可能感兴趣的:(STL与泛型编程<四>:List)