【C++初阶】list的模拟实现

文章目录

  • list的介绍
  • list的模拟实现
    • 成员变量
    • Member functions
      • constructor
      • destructor
      • operator=
    • Iterators
      • 正向迭代器
      • 反向迭代器
      • begin
      • end
      • rbegin
      • rend
    • Modifiers
      • push_front
      • pop_front
      • push_back
      • pop_back
      • insert
      • erase
      • clear
  • 完整版代码
    • list.h
    • reverse_iterator.h
    • test.cpp

list的介绍

list是STL库里面的一个重要容器,它分为一下几个部分
Member functions
【C++初阶】list的模拟实现_第1张图片

Iterators
【C++初阶】list的模拟实现_第2张图片

Capacity
【C++初阶】list的模拟实现_第3张图片

Element access
【C++初阶】list的模拟实现_第4张图片

Modifiers
【C++初阶】list的模拟实现_第5张图片

Operations
【C++初阶】list的模拟实现_第6张图片

Observers
【C++初阶】list的模拟实现_第7张图片

Non-member function overloads
【C++初阶】list的模拟实现_第8张图片

list的模拟实现

我们重点实现list的下面几个部分,其余部分有的还没学到,有的比较简单也不是特别常用大家可以自己去完善。
我们实现的链表结构为带头双向循环链表
【C++初阶】list的模拟实现_第9张图片
_head为哨兵位头节点,是不存储数据的

成员变量

在这里插入图片描述

在这里插入图片描述
_head为哨兵位头节点
节点指针
【C++初阶】list的模拟实现_第10张图片
节点
_prev记录前一个节点的位置
_next记录下一个节点的位置

Member functions

constructor

【C++初阶】list的模拟实现_第11张图片
【C++初阶】list的模拟实现_第12张图片
【C++初阶】list的模拟实现_第13张图片
_head为哨兵位头节点
【C++初阶】list的模拟实现_第14张图片
_head为哨兵位头节点
【C++初阶】list的模拟实现_第15张图片
_head为哨兵位头节点
【C++初阶】list的模拟实现_第16张图片
_head为哨兵位头节点
【C++初阶】list的模拟实现_第17张图片
_head为哨兵位头节点

destructor

【C++初阶】list的模拟实现_第18张图片

【C++初阶】list的模拟实现_第19张图片
_head为哨兵位头节点

operator=

【C++初阶】list的模拟实现_第20张图片
_head为哨兵位头节点

Iterators

链表的正向迭代器和反向迭代器和之前学的string、vector不同,因为它们的物理空间连续可以++、–随机访问它们的各个位置所以它们的迭代器为原生指针,而list的物理空间不连续,不能++、–的随机访问任意位置,所以我们要对list的迭代器进行封装。

正向迭代器

【C++初阶】list的模拟实现_第21张图片

【C++初阶】list的模拟实现_第22张图片

反向迭代器

【C++初阶】list的模拟实现_第23张图片

【C++初阶】list的模拟实现_第24张图片

begin

【C++初阶】list的模拟实现_第25张图片
_head为哨兵位头节点
在这里插入图片描述
_head为哨兵位头节点
const迭代器和普通迭代器的区别在于只可读,不可写

end

【C++初阶】list的模拟实现_第26张图片
_head为哨兵位头节点
【C++初阶】list的模拟实现_第27张图片
_head为哨兵位头节点
const迭代器和普通迭代器的区别在于只可读,不可写

rbegin

【C++初阶】list的模拟实现_第28张图片
【C++初阶】list的模拟实现_第29张图片
const迭代器和普通迭代器的区别在于只可读,不可写

rend

【C++初阶】list的模拟实现_第30张图片
【C++初阶】list的模拟实现_第31张图片
const迭代器和普通迭代器的区别在于只可读,不可写

Modifiers

push_front

【C++初阶】list的模拟实现_第32张图片
复用insert,因为begin()是第一个数据的位置,头插就是要在第一个数据位置的前面插入数据。

pop_front

【C++初阶】list的模拟实现_第33张图片
复用erase,因为begin()是第一个数据的位置,头删是要删除第一个数据的位置。

push_back

【C++初阶】list的模拟实现_第34张图片
复用insert,因为end()是头节点的位置,尾插就是要在头节点前插入数据。(注释部分为不复用的实现方法)

pop_back

【C++初阶】list的模拟实现_第35张图片
复用erase,因为end()是头节点的位置,尾删是要删除头节点的前一个位置,所以要–

insert

【C++初阶】list的模拟实现_第36张图片
【C++初阶】list的模拟实现_第37张图片

erase

【C++初阶】list的模拟实现_第38张图片
【C++初阶】list的模拟实现_第39张图片

clear

【C++初阶】list的模拟实现_第40张图片
【C++初阶】list的模拟实现_第41张图片

完整版代码

list.h

#pragma once
#include"reverse_iterator.h"
namespace lzf
{
	
	template<class T>
	struct ListNode
	{
	public:
		T _data;
		ListNode<T>* _prev;
		ListNode<T>* _next;
		ListNode(const T& val = T())
			:_data(val)
			, _prev(nullptr)
			,_next(nullptr)
		{}
		
	};

	template<class T,class Ref,class Ptr>
	struct list_iterator
	{
		typedef list_iterator<T, Ref, Ptr> self;
		typedef ListNode<T> Node;
		Node* _node;
		list_iterator(Node* x)
			:_node(x)
		{}
		Ref operator*()
		{
			return _node->_data;
		}
		Ptr operator->()
		{
			return &_node->_data;
		}
		self& operator++()
		{
			_node = _node->_next;

			return *this;
		}
		self operator++(int)
		{
			self temp(_node);
			_node = _node->_next;

			return temp;
		}
		self& operator--()
		{
			_node = _node->_prev;

			return *this;
		}
		self operator--(int)
		{
			self temp(_node);
			_node = _node->_prev;

			return temp;
		}
		/*bool operator!=(self& it)
		{
			return _node != it._node;
		}
		bool operator==(self& it)
		{
			return _node == it._node;
		}*/
		/*bool operator!=(self it)
		{
			return _node != it._node;
		}
		bool operator==(self it)
		{
			return _node == it._node;
		}*/
		bool operator!=(const self& it)const
		{
			return _node != it._node;
		}
		bool operator==(const self& it)const
		{
			return _node == it._node;
		}
	};
	

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

		typedef reverse_iterator<iterator, const T&, const T*> const_reverse_iterator;
		typedef reverse_iterator<iterator, T&, T*> reverse_iterator;
		reverse_iterator rbegin()
		{
			return reverse_iterator(end());
		}
		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}
		const_reverse_iterator rbegin()const
		{
			return const_reverse_iterator(end());
		}
		const_reverse_iterator rend()const
		{
			return const_reverse_iterator(begin());
		}
		iterator begin()
		{
			return iterator(_head->_next);
		}
		iterator end()
		{
			return iterator(_head);
		}
		const_iterator begin()const
		{
			return const_iterator(_head->_next);
		}
		const_iterator end()const
		{
			return const_iterator(_head);
		}
		
		list()
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
		}
		list(int n,const T& val = T())
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			for (int i = 0; i < n; i++)
			{
				push_back(val);
			}
		}
		list(size_t n, const T& val = T())
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			for (size_t i = 0; i < n; i++)
			{
				push_back(val);
			}
		}
		template<class Inputiterator>
		list(Inputiterator first, Inputiterator last)
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}
		list(const list<T>& lt)
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			/*const_iterator it = lt.begin();
			while (it != lt.end())
			{
				push_back(*it);
				++it;
			}*/
			list<T> temp(lt.begin(), lt.end());
			std::swap(_head, temp._head);
		}
		list<T>& operator=(list<T> lt)
		{
			/*_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;*/
			std::swap(_head, lt._head);
			return *this;
		}
		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(end(), x);
		}
		void pop_back()
		{
			erase(--end());
		}
		void push_front(const T& x)
		{
			insert(begin(),x);
		}
		void pop_front()
		{
			erase(begin());
		}
		iterator insert(iterator pos, const T& x)
		{
			Node* newnode = new Node(x);
			Node* prev = pos._node->_prev;
			//Node* next = pos._node->_next;

			prev->_next = newnode;
			newnode->_prev = prev;

			pos._node->_prev = newnode;
			newnode->_next = pos._node;

			return iterator(newnode);
		}
		iterator erase(iterator pos)
		{
			assert(pos != end());
			Node* prev = pos._node->_prev;
			Node* next = pos._node->_next;

			delete pos._node;

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


			return iterator(next);
		}
		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);
			}
		}
		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}
	private:
		Node* _head;
	};
	void test_list1()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		list<int>::iterator it = lt.begin();
		while (it != lt.end())
		{
			cout << *it << " ";
			it++;
		}
		//list 
	}
	void test_list2()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		//list lt2(5,1);
		//list lt2(lt.begin(), lt.end());
		//list lt2(lt);
		list<int> lt2;
		lt2.push_back(7);
		lt2.push_back(8);
		lt2.push_back(9);
		lt2.push_back(10);

		//lt.operator=(lt2);
		//list::iterator it = lt.begin();
		/*while (it != lt.end())
		{
			cout << *it << " ";
			it++;
		}*/
		//list 
	}
	void test_list3()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		lt.insert(lt.begin(), 1);
		lt.insert(lt.begin(), 2);
		lt.insert(lt.begin(), 3);
		lt.insert(lt.begin(), 4);
		lt.insert(lt.end(), 4);
		lt.insert(lt.end(), 3);
		lt.insert(lt.end(), 2);
		lt.insert(lt.end(), 1);
		list<int>::iterator it = lt.begin();
		while (it != lt.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;
		lt.erase(lt.begin());
		lt.erase(lt.begin());
		lt.erase(lt.begin());
		lt.erase(lt.begin());
		lt.erase(--lt.end());
		lt.erase(--lt.end());
		lt.erase(--lt.end());
		lt.erase(--lt.end());
		it = lt.begin();
		while (it != lt.end())
		{
			cout << *it << " ";
			it++;
		}

	}
	void test_list4()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		lt.clear();
		list<int>::iterator it = lt.begin();
		while (it != lt.end())
		{
			cout << *it << " ";
			it++;
		}
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		it = lt.begin();
		while (it != lt.end())
		{
			cout << *it << " ";
			it++;
		}
	}
	void test_list5()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		list<int>::reverse_iterator it = lt.rbegin();
		while (it != lt.rend())
		{
			cout << *it << " ";
			//++it;
			it++;
		}
	}
	void test_list6()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		list<int> lt1;
		list<int> lt2;
		lt2 = lt1 = lt;
		list<int>::reverse_iterator it = lt2.rbegin();
		while (it != lt2.rend())
		{
			cout << *it << " ";
			//++it;
			it++;
		}
	}
}

reverse_iterator.h

#pragma once
namespace lzf
{
	template<class iterator, class Ref, class Ptr>
	class reverse_iterator
	{
	public:
		typedef reverse_iterator<iterator, Ref, Ptr> self;
		reverse_iterator(iterator it)
			:_it(it)
		{}
		Ref operator*()
		{
			iterator temp(_it);
			return *--temp;
		}
		Ptr operator->()
		{
			iterator temp(_it);
			return &(*--temp);
		}
		self& operator++()
		{
			--_it;
			return *this;
		}
		self& operator--()
		{
			++_it;
			return *this;
		}
		self operator++(int)
		{
			self temp(_it);
			--_it;
			return temp;
		}
		self operator--(int)
		{
			self temp(_it);
			++_it;
			return temp;
		}
		bool operator!=(const self& it)const
		{

			return _it != it._it;
		}
		bool operator==(const self& it)const
		{

			return _it == it._it;
		}
	private:
		iterator _it;
	};
}

test.cpp

#include
#include
using namespace std;
#include"list.h"
int f()
{
	int a = 10;
	//double& b = a;
	return a;
}
int main()
{
	//int& b = f();
	lzf::test_list6();
	return 0;
}

你可能感兴趣的:(C++初阶和高阶,c++,list,链表)