List的模拟实现

本文详细介绍了如何通过C++语言模拟实现一个简单的List数据结构,包括定义节点、实现链表的基本操作如尾插、头插、头删、尾删,以及迭代器的构造、赋值和交换。还展示了如何测试List类的功能和使用示例。
摘要由CSDN通过智能技术生成

List的模拟实现

List(列表)是一种常见的数据结构,用于存储一系列有序的元素。在本教程中,我们将通过C++语言来模拟实现一个简单的List,并提供一些基本操作,如插入、删除、遍历等。

1. 定义List节点

首先,我们需要定义一个List的节点。每个节点包含数据和指向下一个节点的指针。

	template<class T>
	struct ListNode
	{
		ListNode<T>* _next;
		ListNode<T>* _prev;
		T _data;

		ListNode(const	T& x= T())
			: _next(nullptr)
			, _prev(nullptr)
			, _data(x)
		{}
	};

2. 实现List类

接下来,我们定义一个List类,实现一些简单的接口

( 1 )尾插和头插

这个是正常的通过调整链表的next和prev进行尾插

		void push_back(const T& x)
		{
			Node* newnode = new Node(x);
			Node* tail = _head->_prev;

			tail->_next = newnode;
			newnode->_prev = tail;
			newnode->_next = _head;
			_head->_prev = newnode;
		}

而这样写头插和尾插就会显得很冗杂,所以我们单独写一个insert的函数这样头插和尾插就都可以直接通过insert来实现

		void push_back(const T& x)
		{
			insert(end(), x);
		}

		void push_front(const T& x)
		{
			insert(begin(),x);
		}
		
		void insert(iterator pos, const T& val)
		{
			Node* cur = pos._node;
			Node* newnode = new Node(val);
			Node* prev = cur->_prev;
			_size++;

			//连接关系
			prev->_next = newnode;
			newnode->_prev = prev;
			newnode->_next = cur;
			cur->_prev = newnode;
		}

( 2 )头删和尾删

和头插尾插类似,我们直接写listerase的接口)头删和尾删就能顺利的写出来了

		void pop_back()
		{
			erase(--end());
		}

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

		iterator erase(iterator pos)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;
			_size--;

			prev->_next = next;
			next->_prev = prev;
			delete cur;

			return iterator(next);
		}

( 3 )链表的迭代器,构造,赋值,交换,析构

  1. 构造函数 list()
  • 调用 empty_init() 函数初始化链表。这个函数可能设置了链表的头节点 _head 和大小 _size 。
  1. 构造函数 list(const list<T>& lt)
  • 调用 empty_init() 函数初始化链表。
  • 使用范围for循环遍历传入的链表 lt ,对于每个元素,调用 push_back(e) 方法将元素添加到新链表的末尾。-
  1. swap(list<T>& lt) 函数:
  • 使用 std::swap() 函数交换当前链表的头节点 _head 和大小 _size 与传入链表 lt 的相应成员变量。
  1. 赋值运算符 list<T>& operator=(list<T> lt)
  • 调用 swap(lt) 函数,将当前链表的头节点 _head 和大小 _size 与传入的链表 lt 进行交换。
  • 返回当前链表的引用,以便支持链式赋值(如 lt1 = lt2 = lt3 )。
  1. 私有成员变量:
  • _head :指向链表头节点的指针。
  • _size :表示链表中元素数量的整数。

然后在写const的时候本来想法是写两个struct(即注释的部分)但是之后想到了模板函数这样我写函数的模板来进行const和非const两种迭代器就方便多了

	/*typedef ListIterator<T, T&, T*> iterator;
	typedef ListConstIterator<T, const T&, const T*> const_iterator;*/
	//写模板,编译器生成两个类
	template<class T, class Ref, class Ptr>
	struct  ListIterator
	{
		typedef ListNode<T> Node;
		typedef ListIterator<T, Ref, Ptr> Self;

		Node* _node;

		ListIterator(Node* node)
			:_node(node)
		{}

		//*it
		//T& operator*()
		Ref operator*()
		{
			return _node->_data;
		}

		//it->//
		//T* operator->()
		Ptr operator->()
		{
			return &_node->_data;
		}

		//++it
		Self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		//++it
		Self operator++(int)
		{
			Self tmp(*this);
			_node = _node->_next;

			return tmp;
		}

		//--it
		Self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		Self operator--(int)
		{
			Self tmp(*this);
			_node = _node->_prev;

			return tmp;
		}

		bool operator!=(const Self& it)
		{
			return _node != it._node;
		}

		bool operator==(const Self& it)
		{
			return _node == it._node;
		}
	};


	//template<class T>
	//struct  ListConstIterator
	//{
	//	typedef ListNode<T> Node;
	//	typedef ListConstIterator<T> Self;
	//
	//	Node* _node;
	//
	//	ListConstIterator(Node* node)
	//		:_node(node)
	//	{}
	//
	//	//*it
	//	const T& operator*()
	//	{
	//		return _node->_data;
	//	}
	//
	//	//it->//
	//	const T* operator->()
	//	{
	//		return &_node->_data;
	//	}
	//
	//	//++it
	//	Self& operator++()
	//	{
	//		_node = _node->_next;
	//		return *this;
	//	}
	//
	//	//++it
	//	Self operator++(int)
	//	{
	//		Self tmp(*this);
	//		_node = _node->_next;
	//
	//		return tmp;
	//	}
	//
	//	//--it
	//	Self& operator--()
	//	{
	//		_node = _node->_prev;
	//		return *this;
	//	}
	//
	//	Self operator--(int)
	//	{
	//		Self tmp(*this);
	//		_node = _node->_prev;
	//
	//		return tmp;
	//	}
	//
	//	bool operator!=(const Self& it)
	//	{
	//		return _node != it._node;
	//	}
	//
	//	bool operator==(const Self& it)
	//	{
	//		return _node == it._node;
	//	}
	//};


	template<class T>
	class list
	{
		typedef ListNode<T> Node;
	public:
		/*typedef ListIterator<T> iterator;
		typedef ListConstIterator<T> const_iterator;*/
		typedef ListIterator<T, T&, T*> iterator;
		typedef ListIterator<T, const T&,const T*> const_iterator;

		iterator begin()
		{
			//return iterator(_head->_next);
			return _head->_next;
		}

		iterator end() 
		{
			return _head;
		}

		//因为const迭代器需要的是指向的内容不能被修改,所以const iterator不能用
		const_iterator begin() const
		{
			return _head->_next;
		}

		const_iterator end() const
		{
			return _head;
		}

		void empty_init()
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;

			_size = 0;
		}

		list()
		{
			empty_init();
		}

		//lt2(lt1)
		list(const list<T>& lt)
		{
			empty_init();
			for (auto& e : lt)
			{
				push_back(e);
			}
		}

		void swap(list<T>& lt)
		{
			std::swap(_head, lt._head);
			std::swap(_size,lt._size);
		}

		//lt1 = lt3
		list<T>& operator=(list<T> lt)
		{
			swap(lt);
			return *this;
		}

		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}

	private:
		Node* _head;
		size_t _size;
	}

clear函数

就是用迭代器遍历每个节点之后通过erase进行释放

		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);
			}
		}

链表长度和是否为空值

这里size我就是简单粗暴的每次push和insert就++,每次pop和erase就–
至于判空就是==0进行判断

		size_t size() const
		{
			return _size;
		}

		bool empty()
		{
			return _size == 0;
		}

3. 测试List类

现在我们来测试一下我们的List类
这里的PrintList是遍历const类弄的

	void test_list1()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		lt.push_back(5);

		list<int>::iterator it = lt.begin();
		while (it != lt.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;


		lt.push_front(10);
		lt.push_front(20);
		lt.push_front(30);
		lt.push_front(40);

		for (auto e : lt)
		{
			cout << e << " ";
		}
		cout << endl;

		lt.pop_back();
		lt.pop_back();
		lt.pop_back();

		for (auto e : lt)
		{
			cout << e << " ";
		}
		cout << endl;

		lt.pop_font();

		for (auto e : lt)
		{
			cout << e << " ";
		}
		cout << endl;
	}

	void PrintList(const list<int>& clt)
	{
		list<int>::const_iterator it = clt.begin();
		while (it!=clt.end())
		{
			//*it += 10;
			cout << *it << " ";
			it++;
		}
		cout << endl;
	}

	void test_list2()
	{
		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);

		PrintList(lt);

		list<int> lt1(lt);
		PrintList(lt1);
		/*lt.clear();
		PrintList(lt);*/
	}

4.代码完整版

namespace mylist
{
	template<class T>
	struct ListNode
	{
		ListNode<T>* _next;
		ListNode<T>* _prev;
		T _data;

		ListNode(const	T& x= T())
			: _next(nullptr)
			, _prev(nullptr)
			, _data(x)
		{}
	};

	/*typedef ListIterator<T, T&, T*> iterator;
	typedef ListConstIterator<T, const T&, const T*> const_iterator;*/
	//写模板,编译器生成两个类
	template<class T, class Ref, class Ptr>
	struct  ListIterator
	{
		typedef ListNode<T> Node;
		typedef ListIterator<T, Ref, Ptr> Self;

		Node* _node;

		ListIterator(Node* node)
			:_node(node)
		{}

		//*it
		//T& operator*()
		Ref operator*()
		{
			return _node->_data;
		}

		//it->//
		//T* operator->()
		Ptr operator->()
		{
			return &_node->_data;
		}

		//++it
		Self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		//++it
		Self operator++(int)
		{
			Self tmp(*this);
			_node = _node->_next;

			return tmp;
		}

		//--it
		Self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		Self operator--(int)
		{
			Self tmp(*this);
			_node = _node->_prev;

			return tmp;
		}

		bool operator!=(const Self& it)
		{
			return _node != it._node;
		}

		bool operator==(const Self& it)
		{
			return _node == it._node;
		}
	};


	//template<class T>
	//struct  ListConstIterator
	//{
	//	typedef ListNode<T> Node;
	//	typedef ListConstIterator<T> Self;
	//
	//	Node* _node;
	//
	//	ListConstIterator(Node* node)
	//		:_node(node)
	//	{}
	//
	//	//*it
	//	const T& operator*()
	//	{
	//		return _node->_data;
	//	}
	//
	//	//it->//
	//	const T* operator->()
	//	{
	//		return &_node->_data;
	//	}
	//
	//	//++it
	//	Self& operator++()
	//	{
	//		_node = _node->_next;
	//		return *this;
	//	}
	//
	//	//++it
	//	Self operator++(int)
	//	{
	//		Self tmp(*this);
	//		_node = _node->_next;
	//
	//		return tmp;
	//	}
	//
	//	//--it
	//	Self& operator--()
	//	{
	//		_node = _node->_prev;
	//		return *this;
	//	}
	//
	//	Self operator--(int)
	//	{
	//		Self tmp(*this);
	//		_node = _node->_prev;
	//
	//		return tmp;
	//	}
	//
	//	bool operator!=(const Self& it)
	//	{
	//		return _node != it._node;
	//	}
	//
	//	bool operator==(const Self& it)
	//	{
	//		return _node == it._node;
	//	}
	//};


	template<class T>
	class list
	{
		typedef ListNode<T> Node;
	public:
		/*typedef ListIterator<T> iterator;
		typedef ListConstIterator<T> const_iterator;*/
		typedef ListIterator<T, T&, T*> iterator;
		typedef ListIterator<T, const T&,const T*> const_iterator;

		iterator begin()
		{
			//return iterator(_head->_next);
			return _head->_next;
		}

		iterator end() 
		{
			return _head;
		}

		//因为const迭代器需要的是指向的内容不能被修改,所以const iterator不能用
		const_iterator begin() const
		{
			return _head->_next;
		}

		const_iterator end() const
		{
			return _head;
		}

		void empty_init()
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;

			_size = 0;
		}

		list()
		{
			empty_init();
		}

		//lt2(lt1)
		list(const list<T>& lt)
		{
			empty_init();
			for (auto& e : lt)
			{
				push_back(e);
			}
		}

		void swap(list<T>& lt)
		{
			std::swap(_head, lt._head);
			std::swap(_size,lt._size);
		}

		//lt1 = lt3
		list<T>& operator=(list<T> lt)
		{
			swap(lt);
			return *this;
		}

		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);
			}
		}

		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}

		/*void push_back(const T& x)
		{
			Node* newnode = new Node(x);
			Node* tail = _head->_prev;

			tail->_next = newnode;
			newnode->_prev = tail;
			newnode->_next = _head;
			_head->_prev = newnode;
		}*/
		
		void push_back(const T& x)
		{
			insert(end(), x);
		}

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

		void pop_back()
		{
			erase(--end());
		}

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

		void insert(iterator pos, const T& val)
		{
			Node* cur = pos._node;
			Node* newnode = new Node(val);
			Node* prev = cur->_prev;
			_size++;

			//连接关系
			prev->_next = newnode;
			newnode->_prev = prev;
			newnode->_next = cur;
			cur->_prev = newnode;
		}


		iterator erase(iterator pos)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;
			_size--;

			prev->_next = next;
			next->_prev = prev;
			delete cur;

			return iterator(next);
		}

		size_t size() const
		{
			return _size;
		}

		bool empty()
		{
			return _size == 0;
		}

	private:
		Node* _head;
		size_t _size;
	};


	void test_list1()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		lt.push_back(5);

		list<int>::iterator it = lt.begin();
		while (it != lt.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;


		lt.push_front(10);
		lt.push_front(20);
		lt.push_front(30);
		lt.push_front(40);

		for (auto e : lt)
		{
			cout << e << " ";
		}
		cout << endl;

		lt.pop_back();
		lt.pop_back();
		lt.pop_back();

		for (auto e : lt)
		{
			cout << e << " ";
		}
		cout << endl;

		lt.pop_font();

		for (auto e : lt)
		{
			cout << e << " ";
		}
		cout << endl;
	}

	void PrintList(const list<int>& clt)
	{
		list<int>::const_iterator it = clt.begin();
		while (it!=clt.end())
		{
			//*it += 10;
			cout << *it << " ";
			it++;
		}
		cout << endl;
	}

	void test_list2()
	{
		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);

		PrintList(lt);

		list<int> lt1(lt);
		PrintList(lt1);
		/*lt.clear();
		PrintList(lt);*/
	}
}

看到这里可以点个赞吗?

球球了

  • 42
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值