简单实现list

本文详细解析了C++ STL中list容器的内部实现原理,包括其作为双向循环链表的数据结构特性,以及如何通过定制迭代器实现高效的操作。探讨了list的构造、迭代、容量、访问和修改等关键功能,并通过示例代码展示了如何使用list。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// list作为一个带头结点的双向循环链表,初始状态时有一个空的节点组成双向循环链表。 //
它的优点是插入、删除等操作时不会使其他迭代器失效(甚至进行操作的那个迭代器也不会失效) //
STL算法,使用定制的迭代器而不能使用原生态的指针 //
list实现四种函数构造,resize,push_back,push_front,pop_back,pop_front,insert,erase

1.list实现

#pragma once

namespace bite
{
	// list底层是链表,所以先构建节点
	template <class T>
	struct listNode
	{
		listNode<T>* prev;
		listNode<T>* next;
		T val;

		// 构造函数
		listNode(const T& value = T())
			: prev(nullptr)
			, next(nullptr)
			, val(value)
		{}
	};

	// 因为底层是链表,所以原生态指针失效
	template <class T, class Ref, class Ptr>
	class listiterator
	{
	public:
		typedef listNode<T> Node;
		// 迭代器
		typedef listiterator self;

	public:
		listiterator(Node* node = nullptr)
			:_node(node)
		{}

		// 使其具有指针类似的行为
		Ref operator*()
		{
			return _node->val;
		}

		Ptr operator->()
		{
			// return &(_node->val)
			return &(operator*());
		}


		// 迭代器移动
		// 前置++
		self& operator++()
		{
			_node = _node->next;
			return *this;
		}

		// 后置++
		self operator++(int)
		{
			self temp (*this);
			_node = _node->next;
			return temp;
		}

		// 前置--
		self& operator--()
		{
			_node =  _node->prev;
			return *this;
		}

		// 后置--
		self operator--(int)
		{
			self temp (*this);
			_node = _node->prev;
			return temp;
		}

		// 比较
		bool operator!=(const self& s)const
		{
			return _node != s._node;
		}

		bool operator==(const self& s)const
		{
			return _node == s._node;
		}

		Node* _node;
	};



	template<class T>
	class list
	{
		typedef listNode<T> Node;
		// typedef T* iterator; 不能用原生态指针来进行++操作,因为链表的++ 不一定是下一个节点
		// 链表的下一个节点只能通过next来进行
	public:
		// 下面这种迭代器好操作,可以容易控制const类型的iterator
		typedef listiterator<T, T&, T*> iterator;
		typedef listiterator<T, const T&, const T*> const_iterator;

	public:
		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(list<T>& L)
		{
			CreateHead();
			auto it = L.begin();
			while (it != L.end())
			{
				push_back(*it);
				++it;
			}
		}

		list<T>& operator=(const list<T>& L);

		~list()
		{
			// 1.删除有效节点
			// 2.删除头结点
			erase(begin(), end());
			delete head;
			head = nullptr;
		}

		////////////////////////////////////////////////////
		// 迭代器
		iterator begin()
		{
			return iterator(head->next);
		}

		iterator end()
		{
			// iterator ret(head);
			// return ret;
			return iterator(head);
		}

		// const_iterator
		const_iterator cbegin()const
		{
			return (const_iterator(head->next));
		}

		const_iterator cend()const
		{
			// iterator ret(head);
			// return ret;
			return (const_iterator(head));
		}


		////////////////////////////////////////////////////
		// 容量

		// 访问链表算出size
		size_t size()const
		{
			size_t count = 0;
			auto it = cbegin();
			while (it != cend()) ++it, ++count;
			return count;
		}

		// 判空
		bool empty()const
		{
			return head->next == head;
		}

		// 扩容
		void resize(size_t newsize, const T& data = T())
		{
			size_t oldsize = size();
			if (oldsize > newsize)
			{
				for (size_t i = newsize; i < oldsize; ++i)
					pop_back();
			}
			else
			{
				for (size_t i = oldsize; i < newsize; ++i)
					push_back(data);
			}
		}
		//////////////////////////////////////////////////
		// acess
		int front()
		{
			return head->next->val;
		}

		int front()const
		{
			return head->next->val;
		}

		int back()
		{
			return head->prev->val;
		}

		int back()const
		{
			return head->prev->val;
		}

		///////////////////////////////////////////////
		// 修改
		void push_back(const T& data)
		{
			insert(end(), data);
		}

		void pop_back()
		{
			auto it = end();
			erase(--it);
		}

		void push_front(const T& data)
		{
			insert(begin(), data);
		}

		void pop_front()
		{
			erase(begin());
		}

		// 任意位置的插入(链表的基本操作)
		iterator insert(iterator pos, const T& data)
		{
			Node* newnode = new Node(data);
			newnode->prev = pos._node->prev;
			newnode->next = pos._node;
			newnode->prev->next = newnode;
			pos._node->prev = newnode;
			return iterator(newnode);
		}

		// 任意位置的删除(基操)
		iterator erase(iterator pos)
		{
			// 为了防止迭代器失效,就必须返回下一个节点
			Node* ret = pos._node->next;

			Node* cur = pos._node;
			cur->prev->next = cur->next;
			cur->next->prev = cur->prev;
			delete cur;

			return iterator(ret);
		}

		// 区间删除
		iterator erase(iterator first, iterator last)
		{
			while (first != last)
			{
				first = erase(first);
			}

			return end();
		}

		// 清空链表
		void clear()
		{
			erase(begin(), end());
		}

		void swap(list<T>& L)
		{
			std::swap(head, L.head);
		}

	private:
		// 头节点
		void CreateHead()
		{
			head = new Node;
			head->next = head;
			head->prev = head;
		}
	private:
		Node* head;
	};
};


2.测试代码

#include "list.h"
#include <iostream>
using namespace std;

#include <vector>

void Testlist()
{
	// 测构造函数
	bite::list<int> L1;
	bite::list<int> L2(10, 4);
	auto it = L2.begin();
	while(it != L2.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	vector<int> v{ 1, 2, 3, 4, 5 };
	bite::list<int> L3(v.begin(), v.end());
	for (auto e : L3)
	{
		cout << e << " ";
	}
	cout << endl;

	// 拷贝构造
	bite::list<int> L4(L3);
	for (auto e : L4)
	{
		cout << e << " ";
	}
	cout << endl;
}

// Find函数
template <class Iterator, class T>
Iterator Find(Iterator first, Iterator last, const T& data)
{
	while (first != last)
	{
		if (*first == data)
			return first;
		++first;
	}
	return last;
}

// 测试代码
void Testlist1()
{
	vector<int> v{ 1, 2, 3, 4, 5 };
	bite::list<int> L(v.begin(), v.end());
	for (auto e : L)
		cout << e << " ";
	cout << endl;

	// resize
	L.resize(10);
	for (auto e : L)
		cout << e << " ";
	cout << endl;

	L.resize(4);
	for (auto e : L)
		cout << e << " ";
	cout << endl;

	// push_back
	L.push_back(6);
	cout << L.front() << endl;
	cout << L.back() << endl;

	// pop_back
	L.pop_back();
	cout << L.front() << endl;
	cout << L.back() << endl;

	// push_front
	L.push_front(0);
	cout << L.front() << endl;
	cout << L.back() << endl;

	// pop_front
	L.pop_front();
	cout << L.front() << endl;
	cout << L.back() << endl;

	// insert
	auto it = Find(L.begin(), L.end(), 3);
	if (it != L.end())
	{
		L.insert(it, 10);
		for (auto e : L)
			cout << e << " ";
		cout << endl;
	}

	// erase
	L.erase(it);
	for (auto e : L)
		cout << e << " ";
	cout << endl;

	// 清空
	L.erase(L.begin(), L.end());
}

int main()
{
	// Testlist();
	Testlist1();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值