Loading

C++ STL list

list

list 是双向循环列表,使用需要先包含 <list> 头文件。

优点:

  • 动态内存分配,不会造成内存浪费
  • 可快速在任意位置插入或删除元素

缺点:

  • 遍历速度比数组慢
  • 需要额外的空间存储指针

构造函数

原型 描述
default (1) list();
explicit list (const allocator_type& alloc);
默认构造函数,返回空列表
fill (2) explicit list (size_type n, const allocator_type& alloc = allocator_type());
list (size_type n, const value_type& val, const allocator_type& alloc = allocator_type());
使用 n 个 val 初始化(未指定 val 则使用对应类型的默认初始值)
range (3) template <class InputIterator>
list (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
[first, last) 区间中的元素拷贝
copy (4) list (const list& x);
list (const list& x, const allocator_type& alloc);
拷贝构造函数
move (5) list (list&& x);
list (list&& x, const allocator_type& alloc);
initializer list (6) list (initializer_list<value_type> il, const allocator_type& alloc = allocator_type());

示例:

// 打印 list
void printList(const list<int> lst) {
    for (auto elem: lst) {
        cout << elem << " ";
    }

    cout << endl;
}

// 测试构造函数
void testConstructor() {
    // 默认构造函数,创建空链表
    list<int> c1;
    cout << "c1: ";
    printList(c1);

    // 创建包含 3 个元素的链表(元素默认值为 0)
    list<int> c2(3);
    cout << "c2: ";
    printList(c2);

    // 创建包含 5 个值为 2 的元素的链表
    list<int> c3(5, 2);
    cout << "c3: ";
    printList(c3);

    // 拷贝构造函数
    list<int> c4(c3);
    cout << "c4: ";
    printList(c4);

    // 将 [first, last) 区间中的元素拷贝
    cout << "c5: ";
    list<int> c5(c2.begin(), c2.end());
    printList(c5);
}

输出:

c1:
c2: 0 0 0
c3: 2 2 2 2 2
c4: 2 2 2 2 2
c5: 0 0 0

赋值 = | assign

函数 原型 描述
operator= list& operator=(const list& right);
list& operator=(list&& right);
将容器使用另一个容器替换
assign void assign(size_type Count, const Type& Val);
void assign(initializer_list<Type> IList);
template <class InputIterator>
void assign(InputIterator First, InputIterator Last);
清除链表中的所有元素,并将新元素拷贝至目标链表。

示例:

// 测试赋值
void testAssignment() {
    list<int> c1, c2;

    c1.push_back(10);
    c1.push_back(20);
    c1.push_back(30);
    c2.push_back(40);
    c2.push_back(50);
    c2.push_back(60);

    cout << "初始 c1:" << endl;;
    printList(c1);

    // 使用 = 赋值
    cout << "使用 = 赋值" << endl;
    c1 = c2;
    printList(c1);

    // 指定区间赋值
    c1.assign(++c2.begin(), c2.end());
    cout << "指定区间赋值" << endl;
    printList(c1);

    // 指定元素值和个数赋值(7 个 4)
    cout << "指定元素值和个数赋值(7 个 4)" << endl;
    c1.assign(7, 4);
    printList(c1);

    // 使用待插入元素赋值
    cout << "使用待插入元素赋值" << endl;
    c1.assign({ 11, 22, 33, 44 });
    printList(c1);
}

输出:

初始 c1:
10 20 30
使用 = 赋值
40 50 60
指定区间赋值
50 60
指定元素值和个数赋值(7 个 4)
4 4 4 4 4 4 4
使用待插入元素赋值
11 22 33 44

交换 swap

函数 原型 描述
swap void swap(list<Type, Allocator>& right);
friend void swap(list<Type, Allocator>& left, list<Type, Allocator>& right)
交换两个链表的元素。

示例:

// 测试 swap
void testSwap() {
    list<int> c1({ 1, 2, 3 });
    list<int> c2({ 7, 8, 9, 10 });
    cout << "交换前 c1:" << endl;
    printList(c1);
    cout << "交换前 c2:" << endl;
    printList(c2);

    c1.swap(c2);

    cout << "交换后 c1:" << endl;
    printList(c1);
    cout << "交换后 c2:" << endl;
    printList(c2);
}

输出:

交换前 c1:
1 2 3
交换前 c2:
7 8 9 10
交换后 c1:
7 8 9 10
交换后 c2:
1 2 3

大小 size | empty | resize

函数 原型 描述
size size_type size() const; 返回容器中元素个数
empty bool empty() const; 判断是否为空(true 为空)
resize void resize(size_type _Newsize);
void resize(size_type _Newsize, Type val);
为容器指定新大小

示例:

void testCapacity() {
    list<int> c1;

    // 判断 c1 是否为空
    cout << "c1 是否为空:" << c1.empty() << endl;

    // 重新指定大小(使用 10 填充)
    c1.resize(5, 10);
    cout << "resize 后的 c1:" << endl;
    printList(c1);

    // 查看大小
    cout << "c1 的大小为:" << c1.size() << endl;
}

输出:

c1 是否为空:1
resize 后的 c1:
10 10 10 10 10
c1 的大小为:5

插入 push_back | push_front | emplace_back | emplace_front | insert

函数 原型 描述
push_back void push_back(const Type& val);
void push_back(Type&& val);
在容器尾部添加元素
push_front void push_front(const Type& val);
void push_front(Type&& val);
在容器头部添加元素
emplace_back void emplace_back(Type&& val); 在容器尾部增加一个就地构造的元素
emplace_front void emplace_front(Type&& val); 在容器头部增加一个就地构造的元素
insert iterator insert(iterator Where, const Type& Val);
iterator insert(iterator Where, Type&& Val);
void insert(iterator Where, size_type Count, const Type& Val);
iterator insert(iterator Where, initializer_list<Type> IList);
template <class InputIterator>
void insert(iterator Where, InputIterator First, InputIterator Last);
在容器的特点位置增加一个或多个或一个范围的元素

提示:

emplace_back()push_back() 的区别,就在于底层实现的机制不同。push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。

删除 pop_back | pop_front | clear | erase | remove

函数 原型 描述
pop_back void pop_back(); 删除容器尾部的元素
pop_front void pop_front(); 删除容器头部的元素
clear void clear(); 删除容器中的所有元素
erase iterator erase(iterator Where);
iterator erase(iterator first, iterator last);
根据指定的位置或范围,删除一个或多个元素
remove void remove(const Type& val); 删除容器中所有匹配某个特定值的元素

索引 front | back

函数 原型 描述
front reference front();
const_reference front() const;
返回容器第一个元素的参考
back reference back();
const_reference back() const;
返回容器最后一个元素的参考

反转 reverse

函数 原型 描述
reverse void reverse(); 反转容器中元素出现的顺序

示例:

// 测试反转
void testReverse() {
    list<int> c1({ 1, 2, 3, 4, 5 });
    cout << "反转前:" << endl;
    printList(c1);

    c1.reverse();

    cout << "反转后:" << endl;
    printList(c1);
}

输出:

反转前:
1 2 3 4 5
反转后:
5 4 3 2 1

排序 sort

示例:

// 测试排序
void testSort() {
    list<int> c1({ 5, 9, 1, 4, 2, 0, 7, 8, 3, 6 });
    cout << "排序前:" << endl;
    printList(c1);

    c1.sort();

    cout << "排序后(升序):" << endl;
    printList(c1);

    c1.sort(greater<int>());

    cout << "排序后(降序):" << endl;
    printList(c1);
}

输出:

排序前:
5 9 1 4 2 0 7 8 3 6
排序后(升序):
0 1 2 3 4 5 6 7 8 9
排序后(降序):
9 8 7 6 5 4 3 2 1 0

提示:
不支持随机访问迭代器的容器,不可以使用标准的 sort 算法,但内部会提供对应的算法。

对自定义数据类型进行排序,需要向 sort 函数提供比较函数。

posted @ 2021-02-22 17:45  Lambyte  阅读(20)  评论(0)    收藏  举报