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

C++list的模拟实现

为了实现list,我们需要实现三个类

一、List的节点类

template<class T>
struct ListNode
{ListNode(const T& val = T()):_pPre(nullptr),_pNext(nullptr),_val(val){}ListNode<T>* _pPre;ListNode<T>* _pNext;T _val;
};

二、List的迭代器类

template<class T, class Ref, class Ptr>
class ListIterator
{typedef ListNode<T>* PNode;typedef ListIterator<T, Ref, Ptr> Self;
public:ListIterator(PNode pNode = nullptr):_pNode(pNode){}ListIterator(const Self& l):_pNode(l._pNode){}T& operator*(){return _pNode->_val;}T* operator->(){return &(_pNode->_val);}Self& operator++()//前置++{_pNode = _pNode->_pNext;return *this;}Self operator++(int)//后置++{Self tmp(*this);_pNode = _pNode->_pNext;return tmp;}Self& operator--(){_pNode = _pNode->_pPre;return *this;}Self& operator--(int){Self tmp(*this);_pNode = _pNode->_pPre;return tmp;}bool operator!=(const Self& l){return _pNode != l._pNode;}bool operator==(const Self& l){return _pNode == l._pNode;}PNode _pNode;
};

三、List类

1.数据定义相关

template<class T>
class list
{typedef ListNode<T> Node;typedef Node* PNode;
public:typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&, const T&> const_iterator;
private:void CreateHead()//初始化{_pHead = new Node;_pHead->_pNext = _pHead;_pHead->_pPre = _pHead;_size = 0;}PNode _pHead;//头指针size_t _size;
};

2.构造函数相关

public:///// List的构造list(){CreateHead();}list(int n, const T& value = T()){CreateHead();for (int i = 0; i < n; i++){push_back(value);}}template <class Iterator>list(Iterator first, Iterator last){CreateHead();while (first != last){push_back(*first);first++;}}list(const list<T>& l){CreateHead();for (auto& e : l){push_back(e);}}list<T>& operator=(list<T> l){swap(l);return *this;}~list(){clear();delete _pHead;_pHead = nullptr;}

3.迭代器相关

///
// List Iterator
iterator begin()
{return iterator(_pHead->_pNext);
}
iterator end()
{return iterator(_pHead);
}
const_iterator begin() const
{return const_iterator(_pHead->_pNext);
}
const_iterator end() const
{return const_iterator(_pHead);
}

4.容量相关

///
// List Capacity
size_t size()const
{return _size;
}
bool empty()const
{return _size == 0;
}

5.数据访问相关


// List Access
T& front()
{return _pHead->_pNext->_val;
}
const T& front()const
{return _pHead->_pNext->_val;
}
T& back()
{return _pHead->_pPre->_val;
}
const T& back()const
{return _pHead->_pPre->_val;
}

6.修改数据相关


// List Modify
void push_back(const T& val) 
{ insert(end(), val); 
}
void pop_back() 
{ erase(--end());
}
void push_front(const T& val) 
{ insert(begin(), val); 
}
void pop_front() 
{ erase(begin()); 
}
// 在pos位置前插入值为val的节点
void insert(iterator pos, const T& val)
{PNode pcur = pos._pNode;PNode newnode = new Node(val);PNode prev = pcur->_pPre;newnode->_pNext = pcur;newnode->_pPre = prev;pcur->_pPre = newnode;prev->_pNext = newnode;_size++;
}
// 删除pos位置的节点,返回该节点的下一个位置
iterator erase(iterator pos)
{PNode pdel = pos._pNode;PNode prev = pdel->_pPre;PNode next = pdel->_pNext;next->_pPre = prev;prev->_pNext = next;delete pdel;_size--;return iterator(next);
}
void clear()
{iterator it = begin();while (it != end()){it = erase(it);}
}
void swap(list<T>& l)
{std::swap(_pHead, l._pHead);std::swap(_size, l._size);
}

四、测试一下我们自己写的List

所用测试程序test.cpp

#include"List.h"
using namespace std;
///
// 对模拟实现的list进行测试
// 正向打印链表
template<class T>
void PrintList(const bite::list<T>& l)
{auto it = l.begin();while (it != l.end()){cout << *it << " ";++it;}cout << endl;
}// 测试List的构造
void TestBiteList1()
{cout << "-----------------TestBiteList1()-----------------" << endl;bite::list<int> l1;bite::list<int> l2(10, 5);PrintList(l2);int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };bite::list<int> l3(array, array + sizeof(array) / sizeof(array[0]));PrintList(l3);bite::list<int> l4(l3);PrintList(l4);l1 = l4;PrintList(l1);
}// PushBack()/PopBack()/PushFront()/PopFront()
void TestBiteList2()
{cout << "-----------------TestBiteList2()-----------------" << endl;// 测试PushBack与PopBackbite::list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);PrintList(l);l.pop_back();l.pop_back();PrintList(l);l.pop_back();cout << l.size() << endl;// 测试PushFront与PopFrontl.push_front(1);l.push_front(2);l.push_front(3);PrintList(l);l.pop_front();l.pop_front();PrintList(l);l.pop_front();cout << l.size() << endl;
}// 测试insert和erase
void TestBiteList3()
{cout << "-----------------TestBiteList3()-----------------" << endl;int array[] = { 1, 2, 3, 4, 5 };bite::list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto pos = l.begin();l.insert(l.begin(), 0);PrintList(l);++pos;l.insert(pos, 2);PrintList(l);l.erase(l.begin());l.erase(pos);PrintList(l);// pos指向的节点已经被删除,pos迭代器失效cout << *pos << endl;auto it = l.begin();while (it != l.end()){it = l.erase(it);}cout << l.size() << endl;
}
int main()
{TestBiteList1();TestBiteList2();TestBiteList3();return 0;
}

测试结果

http://www.lryc.cn/news/329302.html

相关文章:

  • Leetcode 187. 重复的DNA序列
  • 都江堰泛计算操作系统(多机)应用方向
  • 【第十二届“泰迪杯”数据挖掘挑战赛】【2024泰迪杯】B题基于多模态特征融合的图像文本检索—解题全流程(论文更新)
  • 蓝桥杯22年第十三届省赛-统计子矩阵|一维前缀和加双指针
  • SaaS 电商设计 (十) 记一次 5000kw 商品数据ES迁移 (详细的集群搭建以及线上灰度过程设计)
  • linux安装Tomcat
  • 【机器学习300问】57、机器是如何读得懂文本数据的呢?
  • 了解XSS和CSRF攻击与防御
  • NEO 学习之 MLE(最大似然估计)
  • going和Java对比有什么不同
  • RabbitMQ面经 手打浓缩版
  • JavaScript引用数据类型
  • Mac m1 Flink的HelloWorld
  • 3.1 Python变量的定义和使用
  • OceanBase中左外连接和反连接的经验分享
  • 如何提升公众号搜索量?分享内部运营的5步优化技术!
  • 【2024】根据系统平均负载情况排查隐患
  • 分类任务中的评估指标:Accuracy、Precision、Recall、F1
  • android 音视频基础知识--个人笔记
  • 信息工程大学第五届超越杯程序设计竞赛(同步赛)题解
  • Python:文件读写
  • 10.windows ubuntu 组装软件:spades,megahit
  • K8S之Secret的介绍和使用
  • git下载安装教程
  • 《剑指 Offer》专项突破版 - 面试题 98、99 和 100 : 和动态规划相关的矩阵路径问题(C++ 实现)
  • KY145 EXCEL排序(用Java实现)
  • 属性选择器
  • 软考 - 系统架构设计师 - 关系模型的完整性规则
  • 写了几个难一点的sql
  • 【JDK常用的API】包装类