底层:
双向链表
特点:
1、可在任意位置插入删除元素,不支持随机访问,在插入、删除元素后,原来的迭代器可能会失效
2、由于链表是通过指针连接的,所以每个元素都需要额外的开销
3、存储的元素位置不连续,遍历方面效率会低于vector
和vector的区别:
1、数据存储结构不同:vecotr采用连续的动态数组,list采用双向链表,内存不连续
2、vector在插入和删除某个元素时,需要移动该元素后的所有元素位置,最坏情况下时间复杂度为o(n);list只需要调整相邻元素的指针即可,时间复杂度为o(1)
3、vector支持随机访问,list不支持随机访问
4、vector在创建的时候会预设一段空间,内存不足时会重新分配一片空间,并复制原来的元素到新的内存中;list不需要,只会在插入元素时动态分配内存
成员方法:
1、构造和析构函数
explicit list(const Allocator& = Allocator());
explicit list(size_type count, const T& value = T(),const Allocator& = Allocator());
template <class InputIt>
list(InputIt first, InputIt last, const Allocator& = Allocator());
2、迭代器
iterator begin() noexcept;
const_iterator begin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
3、容量和大小
bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() const noexcept;
4、插入和删除
void clear() noexcept;
iterator insert(const_iterator pos, const T& value);
iterator insert(const_iterator pos, T&& value);
iterator insert(const_iterator pos, size_type count, const T& value);
template <class InputIt>
iterator insert(const_iterator pos, InputIt first, InputIt last);
iterator insert(const_iterator pos, std::initializer_list<T> ilist);
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);
void push_front(const T& value);
void push_front(T&& value);
void pop_front();
void push_back(const T& value);
void push_back(T&& value);
void pop_back();
void resize(size_type count);
void resize(size_type count, const value_type& value);
void swap(list& other) noexcept(std::allocator_traits<Allocator>::is_always_equal::value);
5、访问
reference front();
const_reference front() const;
reference back();
const_reference back() const;
6、移动
list(list&& other) noexcept;
list& operator=(list&& other) noexcept;
void swap(list& other) noexcept(std::allocator_traits<Allocator>::is_always_equal::value);
7、其他
void remove(const T& value);
template<class Predicate>
void remove_if(Predicate pred);
void unique();
template<class BinaryPredicate>
void unique(BinaryPredicate binary_pred);
void sort();
template<class Compare>
void sort(Compare comp);
void reverse() noexcept;
成员方法使用示例:
#include<iostream>
#include<list>
int main()
{
//1、构造
//创建空列表
std::list<int> listDemo;
//创建大小为10,且所有元素为5的列表
std::list<int> listDemo(10, 5);
std::list<int> listDemo = {1, 2, 3, 4, 5};
//通过迭代器创建列表
int arr[5] = { 1, 2, 3, 4, 5 };
std::list<int> listDemo(arr, arr + 5);
//2、迭代器
//正向迭代器
for (std::list<int>::iterator it = listDemo.begin(); it != listDemo.end(); it++) {
std::cout << *it << " ";
}
//反向迭代器
for (std::list<int>::reverse_iterator rit = listDemo.rbegin(); rit != listDemo.rend(); rit++) {
std::cout << *rit << " ";
}
//常量迭代器
for (std::list<int>::const_iterator cit = listDemo.begin(); cit != listDemo.end(); cit++) {
std::cout << *cit << " ";
}
//常量反向迭代器
for (std::list<int>::const_reverse_iterator crit = listDemo.rbegin(); crit != listDemo.rend(); crit++) {
std::cout << *crit << " ";
}
//3、容量和大小
//判断是否为空
if (listDemo.empty()) {
std::cout << "listDemo is empty!" << std::endl;
}
else {
std::cout << "listDemo size:" << listDemo.size() << std::endl;
}
//4、插入和删除
//---clear---//
listDemo.clear();
//---insert---//
std::list<int>::iterator it = listDemo.begin();
//当前迭代器it为正向迭代器,向前移动两位,表示第三位,第三位插入6
std::advance(it, 2);
listDemo.insert(it, 6);
//第3位插入3个7
std::list<int>::iterator it = listDemo.begin();
std::advance(it, 2);
listDemo.insert(it, 3, 7);
//第三位插入另一个列表中的元素
std::list<int> _listDemo = {8, 9, 10};
it = listDemo.end();
//向后移动1位
std::advance(it, -1);
listDemo.insert(it, _listDemo.begin(), _listDemo.end());
//第1位插入列表多个元素
listDemo.insert(listDemo.begin(), {11, 12, 13, 14, 15});
//---erase---//
std::list<int>::iterator it = listDemo.begin();
//删除第1个元素
std::advance(it, 0);
listDemo.erase(it);
//删除第2个后面的所有元素
it = listDemo.begin();
std::advance(it, 2);
listDemo.erase(it, listDemo.end());
//删除第2个到第四个元素
auto it_start = std::next(listDemo.begin(), 1);
auto it_end = std::next(listDemo.begin(), 3);
listDemo.erase(it_start, it_end);
//---push_front && pop_front---//
//头部插入0
listDemo.push_front(0);
//删除第一个元素
listDemo.pop_front();
//---resize---//调整列表的大小,如果新的大小小于当前列表,则删除多余元素;如果大于当前大小,则添加默认构造值或指定值
listDemo.resize(10);
//使用指定值填充
listDemo.resize(10, 2);
//5、访问
//访问第一个和最后一个元素
int& first = listDemo.front();
const int& back = listDemo.back();
first = 12;
//back = 7 这里编译会报错,因为只能访问不能修改,如果要修改建议写为 int& back = listDemo.back();
//6、移动
std::list<int> list_1 = {1, 2, 3};
std::list<int> list_2 = {4, 5, 6};
//移动构造
std::list<int> list_3(std::move(list_1));
//移动赋值
list_2 = std::move(list_3);
//swap
list_1.swap(list_2);
//7、其他
std::list<int> list_demo = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
//remove -> 删除指定元素
//删除元素2
list_demo.remove(2);
//remove_if -> 从列表中删除满足给定条件的所有元素
//删除偶数
list_demo.remove_if([](int n) {return n % 2 == 0; });
//unique -> 移除重复元素
list_demo.unique();
//sort -> 排序
//降序排序
list_demo.sort(std::greater<int>());
//reverse -> 列表中的元素逆序排列
list_demo.reverse();
return 0;
}
list类部分方法自定义示例
template<typename T>
class MyList {
private:
struct Node {
T data;
Node* prev;
Node* next;
Node(const T& d = T{}, Node* p = nullptr, Node* n = nullptr)
: data(d), prev(p), next(n) {}
};
int size_;
Node* head_;
Node* tail_;
public:
// 构造函数和析构函数
MyList() : size_(0), head_(new Node()), tail_(new Node()) {
head_->next = tail_;
tail_->prev = head_;
}
~MyList() {
clear();
delete head_;
delete tail_;
}
// 添加元素
void push_front(const T& val) {
insert(begin(), val);
}
void push_back(const T& val) {
insert(end(), val);
}
// 删除元素
void pop_front() {
erase(begin());
}
void pop_back() {
erase(--end());
}
void clear() {
while (!empty()) {
pop_front();
}
}
// 获取迭代器
class iterator {
public:
iterator() : node_(nullptr) {}
iterator(Node* n) : node_(n) {}
iterator& operator++() {
node_ = node_->next;
return *this;
}
iterator& operator--() {
node_ = node_->prev;
return *this;
}
bool operator==(const iterator& rhs) const {
return node_ == rhs.node_;
}
bool operator!=(const iterator& rhs) const {
return !(*this == rhs);
}
T& operator*() const {
return node_->data;
}
private:
Node* node_;
friend class MyList<T>;
};
iterator begin() {
return iterator(head_->next);
}
iterator end() {
return iterator(tail_);
}
// 访问元素
T& front() {
return *begin();
}
T& back() {
return *(--end());
}
// 判断容器是否为空
bool empty() const {
return size_ == 0;
}
// 获取容器大小
int size() const {
return size_;
}
// 插入元素
iterator insert(iterator pos, const T& val) {
Node* prev_node = pos.node_->prev;
Node* new_node = new Node(val, prev_node, pos.node_);
prev_node->next = new_node;
pos.node_->prev = new_node;
++size_;
return iterator(new_node);
}
// 删除元素
iterator erase(iterator pos) {
Node* prev_node = pos.node_->prev;
Node* next_node = pos.node_->next;
prev_node->next = next_node;
next_node->prev = prev_node;
iterator it(next_node);
delete pos.node_;
--size_;
return it;
}
};