list
list简介
list是一个双向循环链表,他的插入删除操作用时间是常数级别(O(1)),对空间上的运用精准,不浪费一点空间,
list 简单函数使用:
初始化:
list<Type> a; //定义一个Type类型的链表a
list<Type> a(10); //定义一个Type类型的链表a,并设置初始大小为10
list<Type> a(10, 1); //定义一个Type类型的链表a,并设置初始大小为10,且初始值都为1
list<Type> a(b); //定义并用链表b初始化链表a_
迭代器:
list是双向迭代器:(正向迭代器、反向迭代器)+const(是否只读)
正向迭代器: 语法: list<类型> ::iterator name=… 加const(const_iterator)可读 不可写
reverse 逆置
反向迭代器: 语法: list<类型> ::reverse_iterator name=… 加const(const_iterator)可读 不可写
begin(); //链表的第一个元素
end(); //指向最后一个元素的下一个位置
rbegin(); //反向迭代器指针,指向最后一个元素
rend(); //反向迭代器指针,指向第一个元素的前一个元素
插入删除:
push_front(const T & x); //头部添加元素
push_back(const T & x); //尾部添加元素
insert(iteratpr it, const T & x); //任意位置插入一个元素
insert(iterator it, int n, const T & x); //任意位置插入n个相同元素
insert(iterator it, iterator first, iterator last); //插入另一个向量的[first,last]间的数据
pop_front(); //头部删除元素
pop_back(); //尾部删除元素
erase(iterator it); //任意位置删除一个元素
erase(iterator first, iterator last); //删除[first, last]之间的元素
clear(); //清空所有元素
容器大小:
empty(); //判断链表为空
size(); //容器大小
resize(); //重置有效元素个数
访问首位元素:
front(); //访问链表中第一个元素
back(); //访问链表中最后一个元素
list底层实现:
list的节点
list节点是一个包含节点信息、前指针、后指针的数据结构。
定义如下:
//list结构
template <class T>
struct _list_node
{
typedef _list_node* node;
node prev; //前指针
node next; //后指针
T data; //节点信息
}
list迭代器
list迭代器,是由指针实现,由于list容器的结构时链表所以当,插入数据时,迭代器不会失效(与vector 不同),但是当前节点被删除时,指向该节点的迭代器一样会失效。
实现如下:
//list迭代器
template<class T>
struct list_iterator
{
typedef list_iterator<T> it;
typedef list_node<T>* node;
node ptr;//成员
list_iterator(node p = nullptr) :ptr(p) {} //构造
};
重载个别运算符:
//重载运算符
//取值符
T& operator*()
{
return ptr->data;
}
//前加加
it& operator++()
{
ptr = ptr->next;
return *this;
}
//不等
bool operator!=(const list_iterator& n)
{
return this->ptr!=n.ptr;
}
//其他符类推
//.......
list 类基本构造:
//list 类
template<class T>
class new_list
{
typedef list_node<T> node;
private:
node* ln; //list指针
public:
new_list() //构造
{
ln = new node();
//循环双向链表 先指向自己
ln->next = ln;
ln->prev = ln;
}
void push_back(const T& t )
{
//新节点
node* nd = new node(t);
//尾节点 (因循环 则头节点前尾节点)
node* tail = ln->prev;
//更替节点链接 (实现插入)
tail->next = nd;
nd->prev = tail;
nd->next = ln;
ln->prev = nd;
}
// 迭代起点
list_iterator<T> begin()
{
return (node*)ln->next;
}
// 迭代终点
list_iterator<T> end()
{
return (node*)ln;
}
//其他函数
//......
}
简单使用测试:
源码:
#include<iostream>
#include<list>
using namespace std;
//const_iterator 只可读
void print_list(const list<int>& lis)
{
list<int>:: const_iterator it1 = lis.begin();
while (it1 != lis.end())
{
cout << *it1 << " ";
++it1;
}
cout << endl;
}
//迭代器
void lis_iterator()
//(正向迭代器、反向迭代器)+const
//list迭代器属于双向迭代器类型
{
list<int> lis;
for (int i = 0; i < 7; ++i)
{
lis.push_back(i);
}
//普通迭代器 可读可写
list<int>::iterator it1 = lis.begin();
while (it1 != lis.end())
{
*it1 += 10;
cout << *it1 << " ";
++it1;
}
cout << endl;
//const_iterator 可读不可写
print_list(lis);
//范围for迭代器 (范围for 需容器有迭代器)
for(auto & l:lis)
//for (auto l : lis)
//这种不能修改容器实际值 加&可改
{
l += 10;
cout << l << " ";
}
cout << endl;
//print_list(lis);
//reverse 逆置
//反向迭代器
list<int> ::reverse_iterator rit1 = lis.rbegin();
while (rit1 != lis.rend())
{
cout << *rit1 << " ";
++rit1;
}
cout << endl;
}
//头尾、任意位 操作
void back_front_list()
{
//list 底层是链表 插入数据时 迭代器不会失效
//vector 底层是数组 插入删除时 迭代器还只向旧的空间位置 (即 :失效)
list<int> lis;
for (int i = 0; i < 7; i++)
{
lis.push_back(i);
lis.push_front(-i);
}
print_list(lis);
//任意位
//insert 插入 插入目标迭代所指之前
//erase 删除 删除当前迭代所指
list<int> ::iterator it1 = find(lis.begin(), lis.end(), 5);
lis.insert(it1, 45);
//list 迭代并不会失效 *it1还是5
print_list(lis);
//删除迭代 ,迭代就没了 也会失效
lis.erase(it1);
print_list(lis);
}
namespace new_list
{
//list结构
template <class T>
struct list_node
{
typedef list_node* node;
node prev;//前指针
node next;//后指针
T data;//信息
list_node()
{
prev = nullptr;
next = nullptr;
data = NULL;
}
list_node(const T& t)
{
prev = nullptr;
next = nullptr;
data =t;
}
};
//list迭代器
template<class T>
struct list_iterator
{
typedef list_iterator<T> it;
typedef list_node<T>* node;
node ptr;//成员
list_iterator(node p = nullptr) :ptr(p) {} //构造
//重载运算符
//取值符
T& operator*()
{
return ptr->data;
}
//前加
it& operator++()
{
ptr = ptr->next;
return *this;
}
bool operator!=(const list_iterator& n)
{
return this->ptr!=n.ptr;
}
//同类类推
//.......
};
//list 类
template<class T>
class new_list
{
typedef list_node<T> node;
private:
node* ln; //list指针
public:
new_list() //构造
{
ln = new node();
//循环链表 先指向自己
ln->next = ln;
ln->prev = ln;
}
void push_back(const T& t )
{
//新节点
node* nd = new node(t);
//尾节点 (因循环 则头节点前尾节点)
node* tail = ln->prev;
//更替节点链接 (实现插入)
tail->next = nd;
nd->prev = tail;
nd->next = ln;
ln->prev = nd;
}
// 迭代起点
list_iterator<T> begin()
{
return (node*)ln->next;
}
// 迭代终点
list_iterator<T> end()
{
return (node*)ln;
}
//其他函数
//......
};
}
int main()
{
//原 list使用
lis_iterator();
back_front_list();
//自制半成品list
new_list::new_list<int> lis;
for (int i = 0; i < 5; ++i)
{
lis.push_back(i);
}
new_list::list_iterator<int> it = lis.begin();
while (it != lis.end())
{
cout << *it << " ";
++it;
}
return 0;
}
结果:
…