C++list的模拟实现

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

一、List的节点类

cpp 复制代码
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的迭代器类

cpp 复制代码
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.数据定义相关

cpp 复制代码
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.构造函数相关

cpp 复制代码
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.迭代器相关

cpp 复制代码
///
// 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.容量相关

cpp 复制代码
///
// List Capacity
size_t size()const
{
	return _size;
}
bool empty()const
{
	return _size == 0;
}

5.数据访问相关

cpp 复制代码
// 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.修改数据相关

cpp 复制代码
// 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

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与PopBack
	bite::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与PopFront
	l.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;
}

测试结果

相关推荐
脉牛杂德42 分钟前
多项式加法——C语言
数据结构·c++·算法
legend_jz44 分钟前
STL--哈希
c++·算法·哈希算法
CSUC1 小时前
【C++】父类参数有默认值时子类构造函数列表中可以省略该参数
c++
Vanranrr1 小时前
C++ QT
java·c++·qt
鸿儒5171 小时前
C++ lambda 匿名函数
开发语言·c++
van叶~2 小时前
算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝
c++·算法
knighthood20012 小时前
解决:ros进行gazebo仿真,rviz没有显示传感器数据
c++·ubuntu·ros
半盏茶香3 小时前
【C语言】分支和循环详解(下)猜数字游戏
c语言·开发语言·c++·算法·游戏
小堇不是码农3 小时前
在VScode中配置C_C++环境
c语言·c++·vscode
Jack黄从零学c++3 小时前
C++ 的异常处理详解
c++·经验分享