C++(List的模拟实现)

本文详细介绍了C++中的双向链表数据结构,包括成员变量设计、节点类(list_node)、迭代器封装(__list_iterator)以及list类的构造、操作方法,如插入、擦除、遍历等。同时展示了如何在测试函数中运用这些功能。
摘要由CSDN通过智能技术生成

1.成员变量

上一节已知信息 list是带哨兵卫的双向链表链表 ,所以list类成员变量应该有 节点以及节点个数信息

	private:
		//定义哨兵位
		Node* _head;
		//记录插入节点个数
		size_t _size;
 

2.节点类

每个节点应包含指向下一节点指针、上一节点指针以及自身数据的信息

	template<class T>
	//节点最好用struct定义 保证对外是共有 避免class默认私有 的麻烦
	struct list_node
	{
		list_node<T>* _next;
		list_node<T>* _prev;
		T _val;
		//构造函数
		list_node(const T& val = T())
			:_next(nullptr)
			, _prev(nullptr)
			, _val(val)
		{

		}
	};

3.迭代器封装类

3.1类型重定义,定义节点

//定义类模板 Ref迭代器返回的类型。 Ptr指针指向
	template<class T,class Ref,class Ptr>
	// 迭代器封装的类
	struct __list_iterator
	{
		typedef list_node<T> Node;
		//c++中可以这么使用,在内部引用自身类型 (别名)
		typedef __list_iterator <T, Ref, Ptr> self;
			Node* _node;

3.2构造函数

		//构造函数
		__list_iterator(Node* node)
			:_node(node)
		{}

3.3 operator*()

		//Ref代表返回值的类型 在我们这里 可以是T& 也可以是 const T&
		Ref operator*()
		{
			return _node->_val;
		}
	

3.4operator->()

	//Ptr代表返回值的类型,在这里可以是T*
		Ptr operator->()
		{
			return &_node->_val;
		}

3.5operator++()

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

3.6operator++(int)

		//后置++,返回值 因为tmp是临时变量
		self operator++ (int)
		{
			self tmp(*this);
			_node = _node->_next;
			return tmp;

		}

3.7operator--()

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

3.8operator++(int)

		//后置--
		self operator--(int)
		{
			self tmp(*this);

			_node = _node->_prev;

			return tmp;
		}

 3.9比较

		//比较
		bool operator!= (const self& it) const //传的对象是const
		{
			return _node != it._node;
		}
		bool operator== (const self& it) const //
		{
			return _node == it._node;
		}

 4.list类

4.1类型重定义

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

4.2成员函数

4.2.1构造函数

		list()
		{
			empty_init();
		}

4.2.2 初始化函数

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

			_size = 0;
		 }

4.2.3拷贝构造函数

		list(const list<T>& lt)// 拷贝构造
		{
			empty_init();
			for (auto& e : lt)
			{
				push_back(e);
			}

		}

4.2.4交换函数

		//交换
		void swap(const list<T>& lt)
		{
		std:swap(_head, lt._head);
		std:swap(_size, lt._size);
		}
		list<T>& operator= (list<T> lt)
		{
			swap(lt);
			return *this;
		}

4.2.5析构函数

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

4.2.6清除函数

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

			_size = 0;
		}

4.2.7插入insert

		//插入
		iterator insert(iterator pos, const T& x)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* newnode = new Node(x);

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

			newnode->_next = cur;
			cur->_prev = newnode;
			++_size;
			return newnode;
		}

4.2.8 擦除erase

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

			delete cur;
			--_size;
			//返回删除节点的下个位置
			return next;

		}

4.2.9 push_back()

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

4.2.10push_front()

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

		}

4.2.11pop_front()

		void pop_front()
		{
			erase(begin());
		}
		size_t size()
		{
			return _size;
		}

4.2.12 pop_back()

		void pop_back()
		{
			erase(--end());//end()前一个位置
		}

5测试函数

	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())
		{
			(*it) += 1;
			std::cout << *it << " ";
			++it;
		}
		std::cout << std::endl;
		//范围for是傻瓜式替代方式
		for (auto e : lt)
		{
			std::cout << e << " ";
		}
		std::cout << std::endl;

		Print(lt);
	}

	struct A
	{
		A(int a1 = 0, int a2 = 0)
			:_a1(a1)
			, _a2(a2)
		{};
		int _a1;
		int _a2;

	};

	void test2_list2()
	{
		list<A> lt;
		lt.push_back(A(1, 1));
		lt.push_back(A(2, 2));
		lt.push_back(A(3, 3));
		lt.push_back(A(4, 4));

		list<A> ::iterator it = lt.begin();
		while(it != lt.end())
		{
			//对it解引用 得到是结构体对象
			std::cout << (*it)._a1 << " " << (*it)._a2 << std::endl;
			//通过结构体指针指向 -> -> 编译器直接省略成一个
			std::cout << it->_a1 << " " << it->_a2 << std::endl;
			++it;

			
		}
		std::cout << std::endl;
	}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值