当前位置: 首页 > news >正文

list的使用及模拟实现

list的使用

在本篇博客中介绍的list是带头双向循环链表

list的构造函数

在这里插入图片描述
构造包括:默认构造、赋值构造、迭代器构造、拷贝构造

Iterators:

  • begin+end

在这里插入图片描述
在这里插入图片描述
返回迭代器的开始和末尾

  • rbegin+rend

在这里插入图片描述

在这里插入图片描述
返回迭代器的末尾和开始

  • cbegin+cend

在这里插入图片描述

在这里插入图片描述

返回const迭代器的开始与末尾

#include<iostream>
#include<list>using namespace std;void List_Test1()
{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();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;list<int>::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << " ";rit++;}cout << endl;}int main()
{List_Test1();return 0;
}

在这里插入图片描述

Capacity:

  • empty

在这里插入图片描述
判断list是否为空

  • size

在这里插入图片描述
返回list的结点数量

#include<iostream>
#include<list>using namespace std;void List_Test2()
{list<int> lt;cout << lt.empty() << endl;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.push_back(6);cout << lt.empty() << endl;cout << lt.size() << endl;
}int main()
{List_Test2();return 0;
}

在这里插入图片描述

Element access:

  • front

在这里插入图片描述
返回第一个元素

  • back

在这里插入图片描述
返回最后一个元素

#include<iostream>
#include<list>using namespace std;void List_Test3()
{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);cout << lt.front() << endl;cout << lt.back() << endl;
}int main()
{List_Test3();return 0;
}

在这里插入图片描述

需要注意的是list容器不存在[],究竟是什么原因造成这样的结果:

迭代器的分类

按功能分
  • iterator
  • reverse_iterator
  • const_iterator
  • const_reverse_iterator
按性质分
  • 单向迭代器:forward、unordered_map… 只能进行++

  • 双向迭代器:list、map、set… 可以进行++和 - -

  • 随机迭代器:vector、string、deque… 可以进行++、- -、+、-

在这里插入图片描述

随机迭代器包含了双向迭代器包含了单向迭代器,因此随机迭代器可以使用双向迭代器和单向迭代器的算法,而双向迭代器和单向迭代器不能使用随机迭代器的算法。由此可以回答上述问题,因为[]只能在随机迭代器中使用,因此list没有[]

Modifiers:

  • assign

在这里插入图片描述
给容器分配新的内容

  • push_front

在这里插入图片描述
头插

  • pop_front

在这里插入图片描述
头删

  • push_back

在这里插入图片描述
尾插

  • pop_back

在这里插入图片描述
尾删

  • insert

在这里插入图片描述
选择位置插入数据

  • erase

在这里插入图片描述
选择位置删除数据

  • swap

在这里插入图片描述
交换数据

  • resize

在这里插入图片描述
改变容器的大小

  • clear

在这里插入图片描述

清除容器的内容

#include<iostream>
#include<list>using namespace std;void List_Test4()
{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);list<int> lt2;lt2.assign(lt.begin(), lt.end());list<int>::iterator it2 = lt2.begin();while (it2 != lt2.end()){cout << *it2 << " ";it2++;}cout << endl;lt.push_front(10);lt.push_back(20);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;lt.pop_front();lt.pop_back();it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;it = lt.begin();int k = 3;while (k--){it++;}lt.insert(it, 30);lt.erase(it--);it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;lt.swap(lt2);it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;lt.resize(2);it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;lt.clear();cout << lt.empty() << endl;
}int main()
{List_Test4();return 0;
}

在这里插入图片描述

Operations:

  • splice

在这里插入图片描述
将一个链表剪切到另一个链表中

#include<iostream>
#include<list>using namespace std;void List_Test5()
{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);list<int> lt2;lt2.push_back(10);lt2.push_back(20);lt2.push_back(30);lt2.push_back(40);lt.splice(lt.begin(), lt2);list<int>::iterator it2 = lt2.begin();while (it2 != lt2.end()){cout << *it2 << " ";it2++;}cout << endl;list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;
}int main()
{List_Test5();return 0;
}

在这里插入图片描述

  • remove

在这里插入图片描述
删除指定数据

  • remove_if

在这里插入图片描述
删除满足条件的所有数据

#include<iostream>
#include<list>using namespace std;bool signal_digit(const int& v)
{return (v < 10);
}void List_Test6()
{list<int> lt;lt.push_back(10);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.push_back(6);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;lt.remove(4);it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;lt.remove_if(signal_digit);it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;}int main()
{List_Test6();return 0;
}

在这里插入图片描述

  • unique

在这里插入图片描述
删除重复的数,需要有序

  • sort

在这里插入图片描述
将list进行排序(默认是升序)

#include<iostream>
#include<list>using namespace std;void List_Test7()
{list<int> lt;lt.push_back(10);lt.push_back(2);lt.push_back(4);lt.push_back(4);lt.push_back(1);lt.push_back(5);lt.sort();list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;lt.unique();it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;//改成降序greater<int> gt;lt.sort(gt);it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;
}int main()
{List_Test7();return 0;
}

在这里插入图片描述

  • merge

在这里插入图片描述
合并两个list链表

#include<iostream>
#include<list>using namespace std;void List_Test8()
{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);list<int> lt2;lt.push_back(10);lt.push_back(20);lt.push_back(30);lt.push_back(40);lt.push_back(50);lt.push_back(60);lt.merge(lt2);list<int>::iterator it = lt2.begin();while (it != lt2.end()){cout << *it << " ";it++;}cout << endl;it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;
}int main()
{List_Test8();return 0;
}

在这里插入图片描述

  • reverse


反转链表

#include<iostream>
#include<list>using namespace std;void List_Test9()
{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);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;lt.reverse();it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;
}int main()
{List_Test9();return 0;
}

在这里插入图片描述

list的迭代器失效问题

#include<iostream>
#include<list>
using namespace std;int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);auto it = lt.begin();while (it != lt.end()){lt.erase(it);it++;}return 0;
}

当运行这段代码时,程序会崩溃,这是因为erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给
其赋值
修改:

#include<iostream>
#include<list>
using namespace std;int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);auto it = lt.begin();while (it != lt.end()){lt.erase(it++);}return 0;
}

list的模拟实现

  • list.h

实现list的构造函数,部分迭代器的功能,begin()、end()、insert()、push_back()、push_front()、erase()、pop_back()、pop_front()、size()、empty()

#pragma once
#include<assert.h>
#include<iostream>
using namespace std;namespace my_list
{template<class T>class list_node{T _data;list_node<T>* _next;list_node<T>* _prev;list_node(const T& data = T()):_data(data), _next(nullptr), _prev(nullptr){}};//struct是共有,class是私有template<class T, class Ref, class Ptr>struct list_iterator{typedef list_node<T> Node;//这一行代码的加入使得const和非const不需要繁琐的重新写冗余的代码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++(){Self tmp(*this);_node = _node->next;return tmp;}Self& operator--(){Self tmp(*this);_node = _node->prev;return tmp;}bool operator!=(const Self& s){return _node != s._node;}bool operator==(const Self& s){return _node == s._node;}};template<class T>class list{typedef list_node<T> Node;public:typedef list_iterator<T, T&, T*> iterator;typedef list_const_iterator<T, const T&, const T*> const_iterator;iterator begin(){//普通的写法//iterator it(_head->_next);//return  it;//return iterator(_head->_next);return _head->_next;}iterator end(){return _head;}void empty_list(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}list(){empty_list();}~list(){clear();delete _head;_head = nullptr;}list(const list<T>& lt){empty_list();for (auto& e : lt){push_back(e);}}//使得list<int> lt(1,2,3,4,5) 能够实现list(initializer_list<int> il){empty_list();for (auto& e : il){push_back(e);}}list<T>& operator=(list<T>& lt){swap(lt);return *this;}void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}void clear(){auto it = begin();while (it != end()){it = earse(it);}}void push_back(const T& x){//Node* newnode = new Node(x);//Node* tail = _head->_prev;//tail->_next = newnode;//newnode->_next = _head;//newnode->_prev = tail;//_head->_prev = newnode;//_size++;insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void pop_back(){earse(end()--);}void pop_front(){earse(begin());}iterator earse(iterator it){assert(pos != end());Node* prev = it._node->_prev;Node* next = it._node->_next;prev->_next = next;next->_prev = prev;_size--;return next;}iterator insert(iterator it, const T& x){Node* newnode = new Node(x);Node* cur = it._node;Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;_size++;return newnode;}private:Node* _head;size_t _size;};}

相关文章:

  • 玛格丽特鸡尾酒评鉴,玛格丽特酒的寓意和象征
  • 内存种类详解
  • create-vue搭建Vue3项目(Vue3学习2)
  • 使用BlockingQueue简化Java中的生产者-消费者问题
  • 逻辑越权--水平垂直越权(WEB漏洞)
  • 智能修复大模型生成的 JSON 字符串:Python 实现与优化
  • 从单机到生产:Kubernetes 部署方案全解析
  • Unity Editor 扩展:查找缺失的 Image Sprite
  • 【Windows 常用工具系列 22 -- vscode markdown preview 字体大小设置】
  • VSCode|IDEA|PyCharm无缝接入DeepSeek R1实现AI编程
  • 【Elasticsearch】在kibana中能获取已创建的api keys吗?
  • Jenkins忘记admin密码后的恢复步骤
  • 学习海康VisionMaster之间距检测
  • 数据中台产品功能介绍
  • 【区块链】Uniswap详细介绍
  • webrtc 视频直播
  • WiFi那些事儿(七)——802.11速率表
  • 2025-05-06 事业-独立开发项目-记录
  • iPaaS制造案例丨某照明行业头部企业借助谷云科技iPaaS步入数字化转型“快车道”
  • Java引用RabbitMQ快速入门
  • 巴基斯坦军方:印度导弹袭击已造成至少3死14伤
  • 宋涛就许历农逝世向其家属致唁电
  • 江南华南较强降雨扰返程,北方大部需防风沙
  • 上海成五一国内最热门的入境游目的地,国际消费明显提升
  • 马上评|提供情绪价值,也是文旅经济的软实力
  • 释新闻|新加坡大选今日投票:除了黄循财首次挂帅,还有哪些看点