一、基本概念
(一)定义
list:双向链表。list是一种分布式存储的线性表,每个节点分为数据域和指针域,其中指针域中包含一个指向前驱节点的指针和一个指向后续节点的指针,基本模型如下:
(二)特性
1、双向链表:每个元素都有一个前驱和一个后继,这种结构允许在链表的任何位置实现快速的插入和删除而不影响其他元素。插入和删除时间复杂度为O(1)。
2、迭代器:list提供了双向迭代器,支持++和--运算符,能够前后移动,但不支持随机访问,也就是不支持+、-、+=、-=运算。
3、优势和劣势:相对于deque或者vector,在任意位置插入或者删除元素效率较高;但随机访问效率较低。使用场景多为需要频繁插入或者删除元素时。
二、构造函数
(1)list<T>::list(); 默认构造函数
(2)list<T>::list(size_t size); 构造包含size个元素的链表,默认值为0;
(3)list<T>::list(size_t size,T value); 申请size大小链表,初始化为value;
(4)list<T>::list(initializer_list<int> _list); 初始化列表构造;
(5)list<T>::list(list<int>& other); 拷贝构造函数;
(6)list<T::list(iterator begin,iterator end); 指定范围构造;
(7)list<T>::list(list<int>&& other); 移动构造;(c++11)
三、成员函数
(一)迭代器相关函数
begin()和end(); 返回指向首节点迭代器和指向尾节点后面一个位置迭代器;
cbegin()和cend(); begin()和end()的常量迭代器
rbegin()和rend(); begin()和end()的反向迭代器
crbegin()和crend(); begin()和end()的反向常量迭代器
(二)大小相关函数
size_t list<T>::size(); 返回链表当前元素数量
size_t list<T>::max_size(); 返回链表最大容纳元素数量
bool list<T>::empty(); 判断链表是否为空
(三)访问函数
const T& list<T>::front(); 返回第一个元素常量引用;
const T& list<T>::back(); 返回最后一个元素常量引用;
(四)修改函数
void list<T>::push_back(T&value); 尾插
void list<T>::push_front(T&value); 头插
void list<T>::pop_back(); 尾删
void list<T>::pop_front(); 头删
void list<T>::remove(T&value); 删除指定元素
void list<T>::unique(); 删除相邻且重复的后续元素
void list<T>::insert(iterator pos,T&value); 指定位置插入元素,存在插入多个元素、插入区间、插入初始化列表等多个重载
void list<T>::splice(iterator pos,list<T>&other); 指定位置复制插入或者移动插入other链表(指定元素或指定区间的元素)
void list<T>::erase(iterator pos); 删除迭代器指定位置的元素,或者区间
(五)查找函数
list<T>::itrator find(list<T>::iterator first,list<T>::iterator last,const T& value); 查找容器指定区间内的value值第一次出现的位置
int count(list<T>::iterator first,list<T>::iterator last,const T&value); 查找容器指定区间内value的个数
lower_bound(value); 返回指向第一个小于给定value的元素的迭代器
upper_bound(vlaue); 返回指向第一个大于给定value的元素的迭代器
equal_range(value); 返回有序序列中第一个value值和最后一个value值出现位置的区间,返回值为pair类型,叫做对组。原型为pair<typename T,typename K>,代表包含两个数据类型的数据结构。first代表第一个类型,second代表第二个类型。
注意:这些函数不是容器的成员函数
(六)其他函数
list<T>::swap(list<T>&other); 交换两个链表的内容
list<T>::revers(); 翻转链表
list<T>::sort(); 排序函数,默认递增;当链表内元素是自定义类型或者需要递减排序时,需要传入比较函数作为参数。
list<T>::clear(); 清空链表
list<T>::resize(size_t newsize); 改变链表大小,大于原链表大小时,添加初始化元素;小于原链表大小时,从链表后面删除相应元素。
四、排序算法示例
#include<iostream>
using namespace std;
#include<list>
#include<algorithm>
#include<string>
class Person {
public:
string m_Nmae;
int m_Age;
int m_Height;
};
void printPerson(const Person&p) {
cout << "姓名:" << p.m_Nmae << " 年龄:" << p.m_Age << " 身高:" << p.m_Height << endl;
}
bool MyCompare(Person&p1, Person&p2) {
if (p1.m_Age == p2.m_Age) {
return p1.m_Height > p2.m_Height;
}
else {
return p1.m_Age < p2.m_Age;
}
}
void test() {
Person p1 = { "张三",20,170 };
Person p2 = { "李四",30,165 };
Person p3 = { "王五",40,185 };
Person p4 = { "赵六",40,180 };
Person p5 = { "陈七",50,185 };
list<Person>l;
l.push_back(p1);
l.push_back(p3);
l.push_back(p4);
l.push_back(p2);
l.push_front(p5);
for_each(l.begin(), l.end(), printPerson); cout << endl;
l.sort(MyCompare);
for_each(l.begin(), l.end(), printPerson);
}
int main(int argc,char const **argv) {
test();
return 0;
}
例子中对排序多加了一层逻辑,优先年龄排序,年龄相同时根据身高排序。