C/C++总述:Study C/C++-CSDN博客
目录
定义和初始化list对象
list中元素的访问
list的大小与容量
list的增
list的删
list的改
list的模拟实现
C++ 标准库中的 list
是一种双向链表容器,它支持快速的插入和删除操作。
list 容器中各个元素的前后顺序是靠指针来维系的,每个元素都配备了 2 个指针,分别指向它的前一个元素和后一个元素。其中第一个元素的前向指针总为 null,因为它前面没有元素;同样,尾部元素的后向指针也总为 null。
#include <list>
using std::list;
定义和初始化list对象
- 创建一个没有任何元素的空 list 容器:
list<int> lt;
- 创建一个包含 n 个元素的 list 容器:
list<int> lt(10);//创建lt容器,其中包含10个元素,每个元素的值都为相应类型的默认值(int类型的默认值为0)
- 创建一个包含 n 个元素的 list 容器,并为每个元素指定初始值:
list<int> lt(10, 5);//创建了一个包含10个元素并且值都为5个lt容器。
- 在已有 list 容器的情况下,通过拷贝该容器可以创建新的 list 容器:
list<int> lt1(10); list<int> lt2(lt1);//注意:采用此方式,必须保证新旧容器存储的元素类型一致。
- 通过拷贝其他类型容器(或者普通数组)中指定区域内的元素,可以创建新的 list 容器:
//拷贝普通数组,创建list容器 int a[] = { 1,2,3,4,5 }; list<int> lt1(a, a+5); //拷贝其它类型的容器,创建 list 容器 vector<int, 5>ve{ 11,12,13,14,15 }; list<int>lt(ve.begin()+2, ve.end());//拷贝ve容器中的{13,14,15}
list中元素的访问
成员函数 | 功能 |
---|---|
front() | 返回第一个元素的引用。 |
back() | 返回最后一个元素的引用。 |
begin() | 返回指向容器中第一个元素的双向迭代器。 |
end() | 返回指向容器中最后一个元素所在位置的下一个位置的双向迭代器。 |
rbegin() | 返回指向最后一个元素的反向双向迭代器。 |
rend() | 返回指向第一个元素所在位置前一个位置的反向双向迭代器。 |
cbegin() | 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 |
cend() | 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 |
crbegin() | 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 |
crend() | 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 |
list的大小与容量
成员函数 | 功能 |
---|---|
empty() | 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。 |
size() | 返回当前容器实际包含的元素个数。 |
max_size() | 返回容器所能包含元素个数的最大值。这通常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。 |
front() | 返回第一个元素的引用。 |
back() | 返回最后一个元素的引用。 |
list的增
成员函数 | 功能 |
---|---|
push_front() | 在容器头部插入一个元素。 |
push_back() | 在容器尾部插入一个元素。 |
emplace() | 在容器中的指定位置插入元素。该函数和 insert() 功能相同,但效率更高。 |
insert() | 在容器中的指定位置插入元素。 |
splice() | 将一个 list 容器中的元素插入到另一个容器的指定位置。 |
list的删
pop_front() | 删除容器头部的一个元素。 |
pop_back() | 删除容器尾部的一个元素。 |
erase() | 删除容器中一个或某区域内的元素。 |
clear() | 删除容器存储的所有元素。 |
remove(val) | 删除容器中所有等于 val 的元素。 |
remove_if() | 删除容器中满足条件的元素。 |
unique() | 删除容器中相邻的重复元素,只保留一个。 |
list的改
成员函数 | 功能 |
---|---|
assign() | 用新元素替换容器中原有内容。 |
swap() | 交换两个容器中的元素,必须保证这两个容器中存储的元素类型是相同的。 |
resize() | 调整容器的大小。 |
merge() | 合并两个事先已排好序的 list 容器,并且合并之后的 list 容器依然是有序的。 |
sort() | 通过更改容器中元素的位置,将它们进行排序。 |
reverse() | 反转容器中元素的顺序。 |
list的模拟实现
#include<string>
#include<vector>
#include<iostream>using namespace std;
namespace mylist
{template<class T>//链表的每个结点的结构struct list_node {T _data; //存放数据list_node<T>* _prev;//指向前一个结点的指针list_node<T>* _next;//指向后一个结点的指针list_node(const T& val = T()) //构造一个结点对象:_data(val), _prev(nullptr), _next(nullptr){ }};// T T& T*// T cosnt T& const T*template<class T,class Ref,class Ptr>struct __list_iterator //list的迭代器结构{typedef list_node<T> Node; //结点typedef __list_iterator<T,Ref,Ptr> _self; //_self就是一个实例化的迭代器Node* _node; //结点的指针__list_iterator(Node* node):_node(node){}Ref operator*() //重载运算符* 通过*能够访问结点里面的数据{return _node->_data;}Ptr operator->() //重载-> , 结构体指针访问成员可以用结构体对象->结构体成员{return &_node->_data;}_self& operator++() //重载运算符前置++,返回下一个结点的迭代器{_node = _node->_next;return (*this);}_self& operator--() //重载运算符前置--,返回前一个结点的迭代器{_node = _node->_prev;return (*this);}_self operator++(int) //重载运算符后置++,返回当前结点的迭代器的拷贝再++{Node* tmp(_node);_node = _node->_next;return tmp;}_self operator--(int) //重载运算符前置--,返回当前一个结点迭代器的拷贝再--{Node* tmp(_node);_node = _node->_prev;return tmp;}bool operator!=(const _self& n) //重载迭代器的比较运算符!={return this->_node != n._node;}bool operator==(const _self& n) //重载迭代器的比较运算符=={return this->_node == n._node;}};template<class T>class list{typedef list_node<T> Node;public:typedef __list_iterator<T, T&, T*> iterator;typedef __list_iterator<T, const T&, const T*> const_iterator;const_iterator begin() const{return const_iterator(_head->_next);}const_iterator end() const{return const_iterator(_head);}iterator begin(){return (_head->_next);}iterator end(){return _head;}void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}list(){empty_init();}//lt1(lt2)list(const list<T>& lt){empty_init();for (auto e : lt){push_back(e);}}~list(){clear();delete _head;_head = nullptr;}list<int>& operator=(list<int>lt){swap(lt);return *this;}void push_back(const T& x){insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void pop_back(const T& x){erase(--end());}void pop_front(const T& x){erase(begin());}iterator insert(iterator pos, const T& x){Node* newnode = new Node(x);Node* cur = pos._node;Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;++_size;return iterator(newnode);}iterator erase(iterator pos){Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;delete cur;prev->_next = next;next->_prev = prev;--_size;return iterator(next);}size_t size(){return _size;}private:Node* _head; //list的头结点size_t _size;//list的大小};
}