list
目录
一、list模板
**本质:**带头双向循环列表


允许以O(1)的方式(constant time)进行插入与删除

二、list的迭代器
string与vector的数据内存空间是连续的,迭代器是原生指针
而list不是连续的,它的迭代器是自定义类型
**功能:**iterator,reverse_iterator,const_iterator,const_reverse_iterator
性质:
- 单向迭代器(forward_list/unordered_map/unordered_set...,支持++)
- 双向迭代器(list/map/set,支持++/--)
- 随机迭代器(vector/string/deque,支持++/--/+/-)
由底层的结构决定,进一步决定了可以实现哪些算法
示例1:

标准库中的sort算法只能用随机迭代器(底层为快排,需要三数取中和自省优化)
所以list只能自己实现一个sort算法

cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <list>
using namespace std;
void test_list1()
{
list<int> lt;
lt.push_back(25);
lt.push_back(20);
lt.push_back(3);
lt.push_back(400);
lt.push_back(51);
lt.push_back(36);
for (auto e : lt)
{
cout << e << " ";
}
cout << endl;
//默认为升序
lt.sort();
//降序-仿函数(特殊的类)
greater<int> gt;
lt.sort(gt);
for (auto e : lt)
{
cout << e << " ";
}
cout << endl;
}
int main()
{
test_list1();
return 0;
}
示例2:

标准库中的reverse算法只能用双向迭代器
所以list可以使用它实现逆置,而forward_list就无法使用,但vector可以使用
随机迭代器支持单向与双向
双向迭代器支持单向
这是一种概念的继承(子类是特殊的父类)

示例3:

input/output:只读/只写迭代器(单向,双向,随机都可以)
三、list的用法
emplace_back的用法
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <list>
using namespace std;
struct A
{
public:
A(int a1 = 1, int a2 = 1)
:_a1(a1)
,_a2(a2)
{
cout << "A(int a1 = 1,int a2 = 1)" << endl;
}
A(const A& aa)
:_a1(aa._a1)
, _a2(aa._a2)
{
cout << "A(const A& aa)" << endl;
}
int _a1;
int _a2;
};
void test_list1()
{
list<A> lt;
A aa1(1, 1);
lt.push_back(aa1);
lt.push_back(A(2, 2));
lt.emplace_back(aa1);
lt.emplace_back(A(2, 2));
cout << endl;
//区别:
//lt.push_back(3,3);//报错
lt.emplace_back(3,3);//本质:支持传构造A对象的参数
}
int main()
{
test_list1();
return 0;
}

insert 与erase的用法
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <list>
using namespace std;
void test_list1()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);
lt.push_back(6);
for (auto e : lt)
{
cout << e << " ";
}
cout << endl;
auto it = lt.begin();
int k = 3;
while (k--)
{
++it;
}
lt.insert(it, 30);
for (auto e : lt)
{
cout << e << " ";
}
cout << endl;
int x = 0;
cin >> x;
it = find(lt.begin(), lt.end(), x);
if (it != lt.end())
{
lt.erase(it);
}
for (auto e : lt)
{
cout << e << " ";
}
cout << endl;
}
int main()
{
test_list1();
return 0;
}
merge(合并)
本质:取小的尾插
注:前提是两个链表有序

unique(去重)
注:前提是链表有序

remove(查找删除)
注:erase是迭代器删除

splice(剪切粘贴)

用法1:调整当前链表的节点顺序
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <list>
using namespace std;
void test_list1()
{
std::list<int>::iterator it;
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);
lt.push_back(6);
for (auto e : lt)
{
cout << e << " ";
}
cout << endl;
int x = 0;
cin >> x;
it = find(lt.begin(), lt.end(), x);
if (it != lt.end())
{
//转移单个值到前面:lt.splice(lt.begin(), lt, it);
//转移多个值到前面:
lt.splice(lt.begin(), lt, it, lt.end());
}
for (auto e : lt)
{
cout << e << " ";
}
cout << endl;
}
int main()
{
test_list1();
return 0;
}

用法2:转移链表节点到另一个链表
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <list>
using namespace std;
void test_list1()
{
std::list<int> mylist1, mylist2;
std::list<int>::iterator it;
for (int i = 1; i <= 4; ++i)
{
mylist1.push_back(i);
}
for (int i = 1; i <= 3; ++i)
{
mylist1.push_back(i * 10);
}
//mylist1:1 2 3 4
//mylist2:10 20 30
it = mylist1.begin();
++it;
mylist1.splice(it, mylist2);
//mylist1:1 10 20 30 2 3 4
//mylist2:empty
for (auto e : mylist1)
{
cout << e << " ";
}
cout << endl;
}
int main()
{
test_list1();
return 0;
}
list的sort排序效率低于vector,可以将list中的数据拷贝到vector中进行排序,再拷贝回来
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <algorithm>
#include <list>
#include <vector>
using namespace std;
void test_list1()
{
srand(time(0));
const int N = 1000000;
list<int> lt1;
list<int> lt2;
for (int i = 0; i < N; ++i)
{
auto e = rand() + i;
lt1.push_back(e);
lt2.push_back(e);
}
int begin1 = clock();
//将数据拷贝到vector(支持迭代器区间拷贝)
vector<int> v(lt2.begin(), lt2.end());
//排序
sort(v.begin(), v.end());
int end1 = clock();
int begin2 = clock();
lt1.sort();
int end2 = clock();
printf("list copy vector sort copy list sort:%d\,", end1 - begin1);
printf("list sort:%d\,", end2 - begin2);
}
int main()
{
test_list1();
return 0;
}

四、list实现
初始化:构造带哨兵的循环链表

从内存池中申请空间


cpp
#pragma once
#include <assert.h>
namespace bit
{
//链表节点结构的声明
template<class T>
struct list_node
{
T _data;
list_node<T>* _next;
list_node<T>* _prev;
list_node(const T& data = T())
:_data(data)
,_next(nullptr)
,_prev(nullptr)
{ }
};
//创建类类型的迭代器
//使用运算符重载可以解决迭代器访问下一个节点问题
//使用模板可以解决const迭代器与普通迭代器重复问题
template<class T,class Ref,class Ptr>
struct list_iterator
{
typedef list_node<T> Node;
typedef list_iterator<T, Ref, Ptr> 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)
{
Self tmp(*this);
_node = _node->_next;
return tmp;
}
//后置--
Self operator--(int)
{
Self tmp(*this);
_node = _node->_prev;
return tmp;
}
bool operator!=(const Self& s) const
{
return _node != s._node;
}
bool operator==(const Self& s) const
{
return _node == s._node;
}
};
//const_iterator
//template<class T>
//struct list_const_iterator
//{
// typedef list_node<T> Node;
// typedef list_const_iterator<T> Self;
// Node* _node;
// //用节点指针构造迭代器
// list_const_iterator(Node* node)
// :_node(node)
// {
// }
// const T& operator*()
// {
// return _node->_data;
// }
// const T* operator->()
// {
// return &_node->_data;
// }
// //前置++
// Self& operator++()
// {
// _node = _node->_next;
// return *this;
// }
// //前置--
// Self& operator--()
// {
// _node = _node->_prev;
// return *this;
// }
// //后置++
// Self& operator++()
// {
// Self tmp(*this);
// _node = _node->_next;
// return tmp;
// }
// //后置--
// Self& operator--()
// {
// Self tmp(*this);
// _node = _node->_prev;
// return tmp;
// }
// bool operator!=(const Self& s) const
// {
// return _node != s._node;
// }
// bool operator==(const Self& s) const
// {
// return _node == s._node;
// }
//};
template<class T>
class list
{
//链表节点结构的重命名
typedef list_node<T> Node;
public:
//typedef list_iterator<T> iterator;
//typedef list_const_iterator<T> const_iterator;
typedef list_iterator<T,T&,T*> iterator;
typedef list_iterator<T,const T&,const T*> const_iterator;
iterator begin()
{
//iterator it(_head->next);
//return it;
return _head->next;//隐式类型转换
}
iterator end()
{
return _head;
}
const_iterator begin() const
{
return _head->next;
}
const_iterator end() const
{
return _head;
}
//空初始化(创建哨兵位)
void empty_init()
{
_head = new Node;
_head->next = _head;
_head->prev = _head;
_size = 0;
}
//默认构造函数
list()
{
empty_init();
}
list(initializer_list<T> il)
{
empty_init();
for (auto& e : li)
{
push_back(e);
}
}
//拷贝构造函数
list(const list<T>& lt)
{
empty_init();
for (auto& e : lt)
{
push_back(e);
}
}
//交换函数
void swap(list<int>& lt)
{
std::swap(_head,lt._head);
std::swap(_size,lt._size);
}
//赋值运算符重载
list<T>& operator=(list<T> lt)
{
swap(lt);
return *this;
}
//析构函数
~list()
{
clear();
delete _head;
_head = nullptr;
}
void clear()
{
auto it = begin();
while (it != end())
{
it = erase(it);
}
}
//尾插
/*void push_back(const T& x)
{
Node* newnode = new Node(x);
Node* tail = head->prev;
tail->next = newnode;
newnode->prev = tail;
newnode->next = _head;
_head->prev = newnode;
}*/
//尾插
void push_back(const T& x)
{
insert(end(), x);
}
//头插
void push_Front(const T& x)
{
insert(begin(), x);
}
//插入
iterator insert(iterator pos, const T& x)
{
Node* cur = pos._node;
Node* prev = cur->_prev;
Node* newnode = new Node(x);
newnode->_next = cur;
cur->_prev = newnode;
newnode->_prev = prev;
prev->_next = newnode;
++_size;
return newnode;
}
//尾删
void pop_back()
{
erase(--end());
}
//头删
void pop_front()
{
erase(begin());
}
//删除
iterator erase(iterator pos)
{
assert(pos != end());
Node* prev = pos._node->_prev;
Node* next = pos._node->_next;
prev->_next = next;
next->_prev = prev;
delete pos._node;
--size;
return next;
}
//计算节点个数
size_t size() const
{
return _size;
}
//判空
bool empty() const
{
return _size == 0;
}
private:
Node* _head;
size_t _size = 0;
};
struct AA
{
int _a1 = 1;
int _a2 = 2;
};
template<class Container>
void print_container(const Container& con)
{
//const iterator 迭代器本身无法修改
//const_iterator 指向内容不能修改
typename Container::const_iterator it = con.begin();
//auto it = con.begin();
while (it != con.end())
{
cout << *it << " ";
++it;
}
cout << endl;
for (auto e : con)
{
cout << e << " ";
}
cout << endl;
}
void test_list1()
{
list<AA> lta;
//尾插4个AA类型的匿名对象
lta.push_back(AA());
lta.push_back(AA());
lta.push_back(AA());
lta.push_back(AA());
//使用迭代器遍历访问AA中的数据
list<AA>::iterator ita = lta.begin();
while (ita != lta.end())
{
//cout << ita->_a1 << " " << ita->_a2 << " ";
//等价于
//cout << ita.operator->()->_a1 << ":" << ita.operator->()->_a2 << endl;
++ita;
}
}
void test_list2()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
list<int>::iterator it = lt.begin();
//测试插入
//insert以后迭代器不失效
lt.insert(it, 10);
*it += 100;
print_container(lt);
//测试删除
//erase以后迭代器失效
it = lt.begin();
while (it != lt.end())
{
if (*it * 2 == 0)
{
it = lt.erase(it);
}
else
{
++it;
}
}
print_container(lt);
}
//测试拷贝构造
void test_list3()
{
list<int> lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_back(3);
list<int> lt2(lt1);
print_container(lt1);
print_container(lt2);
list<int> lt3;
lt3.push_back(10);
lt3.push_back(20);
lt3.push_back(30);
lt1 = lt3;
print_container(lt1);
print_container(lt3);
}
void func(const list<int>& lt)
{
print_container(lt);
}
void test_list4()
{
//std::list<int> lt1 = { 1,2,3,4,5,6 };
//print_container(lt1);
//auto il = { 10,20,30 };
//initializer_list<int> il = { 10,20,30 };
//cout << typeid(il).name() << endl;//class std::initializer_list<int>
//cout << sizeof(il) << endl;//8
//直接构造
list<int> lt0({ 1,2,3,4,5,6 });
//隐式类型转换
list<int> lt1 = { 1,2,3,4,5,6 };
const list<int>& lt3 = { 1,2,3,4,5,6 };
func(lt0);
func({ 1,2,3,4,5,6 });//隐式类型转换,默认为initializer_list<int>的对象
}
}