list使用及底层结构刨析

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;
} 
结果:

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值