C++:用类模板手撕list容器

目录

list是个双向链表 先定义一个双向链表

封装一个容器类

正序遍历

逆序遍历

尾插

头插

尾删

头删

按指定值删除

返回首尾指针   

一个简单的测试案例


list是个双向链表 先定义一个双向链表
template<typename T>
struct Node
{
	T data;
	Node* prev;
	Node* next;
	Node(const T& d = T{},Node* prev = nullptr,Node* next = nullptr)
		: data(d), prev(prev), next(next) {}
};
封装一个容器类

里面存储链表的头尾指针,然后写一些常用的函数

template<typename T>
class List
{
public:
	List() :head(nullptr), tail(nullptr) {}
	~List();//类外定义,销毁链表

	void print()const;//正序输出
	void rprint()const;//倒序输出
	void push_back(const T& val);//尾插
	void push_front(const T& val);//头插
	void pop_back();//尾删
	void pop_front();//头删
	void remove(const T& val);//指定值删除
	Node<T>* begin();//返回头指针
	Node<T>* end();//返回尾指针

private:
	Node<T>* head;
	Node<T>* tail;
};
正序遍历
template<typename T>
void List<T>::print()const
{
	if (head == nullptr)
	{
		cout << "链表为空" << endl;
		return;
	}

	cout << "head -> ";
	Node<T>* current = head;
	while (current)
	{
		cout << current->data << " -> ";
		current = current->next;
	}
	cout << "tail" << endl;
}
逆序遍历
template<typename T>
void List<T>::rprint()const
{
	if (head == nullptr)
	{
		cout << "链表为空" << endl;
		return;
	}

	cout << "tail -> ";
	Node<T>* current = tail;
	while (current)
	{
		cout << current->data << " -> ";
		current = current->prev;
	}
	cout << "head" << endl;
}
尾插
template<typename T>
void List<T>::push_back(const T& val)
{
	if (tail == nullptr)
	{
		head = new Node<T>(val);
		tail = head;
		return;
	}
	tail->next = new Node<T>(val,tail);
	tail = tail->next;
}
头插
template<typename T>
void List<T>::push_front(const T& val)
{
	if (tail == nullptr)
	{
		head = new Node<T>(val);
		tail = head;
		return;
	}
	head = new Node<T>(val,nullptr,head);
	head->next->prev = head;
}
尾删
template<typename T>
void List<T>::pop_back()
{
	if (tail == nullptr)
	{
		return;
	}

	Node<T>* dest = tail;
	tail = tail->prev;
	tail->next = nullptr;
	delete dest;
}
头删
template<typename T>
void List<T>::pop_front()
{
	if (tail == nullptr)
	{
		return;
	}

	Node<T>* dest = head;
	head = head->next;
	head->prev = nullptr;
	delete dest;
}
按指定值删除

因为是仿写list容器,list容器的remove函数会把所有和指定目标相等的数据全部删除,所以我这个函数也是全部删除

template<typename T>
void List<T>::remove(const T& val)
{
	if (head == nullptr)
	{
		cout << "链表为空" << endl;
		return;
	}

	Node<T>* current = head;
	while (current)
	{
		if (current->data == val)//找到
		{
			Node<T>* temp = current;//记录被删除节点
			current->prev->next = current->next;//前节点指向后节点
			current->next->prev = current->prev;//后节点指向前节点
			current = temp->next;//指针移位
			delete temp;
			continue;
		}
		current = current->next;
	}
}
返回首尾指针   

类似返回首尾迭代器的功能

//返回头指针
template<typename T>
Node<T>* List<T>::begin()
{
	return head;
}

//返回尾指针
template<typename T>
Node<T>* List<T>::end()
{
	return tail;
}

最后删除所有元素,我这里写到析构函数里面了,也可以拿出来单独封装一个函数

template<typename T>
List<T>::~List()
{
	if (tail == nullptr)
		return;

	Node<T>* dest;
	while (head)
	{
		dest = head;
		head = head->next;
		delete dest;
	}
	cout << "链表已销毁" << endl;
}
一个简单的测试案例

测试代码的功能完整性

int main()
{
	List<int>v;
	v.push_back(3);
	v.push_back(3);
	v.push_back(3);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_front(2);
	v.push_front(1);
	v.remove(3);
	v.print();
	v.rprint();

	v.pop_back();
	v.pop_front();
	v.print();
	v.rprint();
	cout <<v.begin()->data << endl;
	cout <<v.end()->data << endl;
}

可以看到,没有任何问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

头发乌黑茂密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值