C/C++总述:Study C/C++-CSDN博客
目录
C++ 标准库中的 list
是一种双向链表容器,它支持快速的插入和删除操作。
list 容器中各个元素的前后顺序是靠指针来维系的,每个元素都配备了 2 个指针,分别指向它的前一个元素和后一个元素。其中第一个元素的前向指针总为 null,因为它前面没有元素;同样,尾部元素的后向指针也总为 null。
cpp
#include <list>
using std::list;
定义和初始化list对象
-
创建一个没有任何元素的空 list 容器:
cpplist<int> lt;
-
创建一个包含 n 个元素的 list 容器:
cpplist<int> lt(10);//创建lt容器,其中包含10个元素,每个元素的值都为相应类型的默认值(int类型的默认值为0)
-
创建一个包含 n 个元素的 list 容器,并为每个元素指定初始值:
cpplist<int> lt(10, 5);//创建了一个包含10个元素并且值都为5个lt容器。
-
在已有 list 容器的情况下,通过拷贝该容器可以创建新的 list 容器:
cpplist<int> lt1(10); list<int> lt2(lt1);//注意:采用此方式,必须保证新旧容器存储的元素类型一致。
-
通过拷贝其他类型容器(或者普通数组)中指定区域内的元素,可以创建新的 list 容器:
cpp//拷贝普通数组,创建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的模拟实现
cpp
#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的大小
};
}