List的模拟实现

List.h

#pragma once
#include<assert.h>
namespace bit
{
	template<class T>
	struct __list_node
	{
		__list_node<T>* _next;
		__list_node<T>* _prev;
		T _data;
		//构造函数,new node需要
		__list_node(const T& x = T())//没有传参就可以调用,当没有传参的时候就应该使用缺省值
			:_next(nullptr)
			, _prev(nullptr)
			, _data(x)
		{}
	};
	// 迭代器-- 用一个类去封装了节点的指针
	//类能运算符重载--实现指针(迭代器)
	//List不能使用原生的指针(地址不连续)了得自己实现
	template<class T, class Ref, class Ptr>//里面使用的Node使用类模板,所以这里也要是类模板
	struct __list_iterator//类
	{
	   //这段代码能实现test_List中需要find的时候出错
	   //typedef bidirectional_iterator_tag iterator_category;
		//typedef T value_type;
		//typedef Ptr pointer;
		//typedef Ref reference;
		//typedef ptrdiff_t difference_type;
	
		typedef __list_iterator<T, Ref, Ptr> self;
		typedef __list_node<T> Node;
		Node* _node;
		//构造函数
		__list_iterator(Node* node)
			:_node(node)
		{}
		//重载*--解引用返回里面的数据
		// *it -> it.operator*()
		//可读可写 *it=10
		Ref operator*()//返回的是data的指针
		{
			return _node->_data;
		}
		Ptr operator->()
		{
			return &_node->_data;
		}
		//重载++, ++it
		// ++it-> it.operator++()
		self& operator++()
		{
			_node = _node->_next;
			return *this;//前置++返回++以后的值
		}
		// it++ -> it.operator++(0)
		self operator++(int)//不能用引用tmp出作用域后会非法,这里传值会拷贝
		{
			self tmp(*this);
			_node = _node->_next;
			return tmp;//后置++返回++之前的
		}
		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}
		self operator--(int)
		{
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}
		// 重载!=,迭代器需要比较相等或者不相等
		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 __list_node<T> Node;
	public:
		//使得迭代器能给外面使用
		typedef __list_iterator<T, T&, T*> iterator;
		typedef __list_iterator<T, const T&, const T*> const_iterator;
		iterator begin()
		{
			return iterator(_head->_next);
		}
		//end为最后一个节点的下一个位置
		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(T());//因为T()不知道类型,所以不能传0,传T类型的匿名对象
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
		}
		//深拷贝
		// lt2(lt1) -- 传统写法
		/*list(const list<T>& lt)
		{
		_head = new Node;
		_head->_next = _head;
		_head->_prev = _head;

		for (const auto& e : lt)//要加引用万一T为String类型则为深拷贝用引用更好
		{
		push_back(e);
		}
		}*/
		template<class InputIterator>//模板
		list(InputIterator first, InputIterator last)//支持所有类型的迭代器来初始化
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;

			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}
		// lt2(lt1) -- 现代写法
		list(const list<T>& lt)
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;

			list<T> tmp(lt.begin(), lt.end());
			std::swap(_head, tmp._head);
		}
		//赋值
		// lt1 = lt4  -- 传统写法
		/*list<T>& operator= (const list<T>& lt)
		{
		if (this != &lt)
		{
		clear();
		for (const auto& e : lt)
		{
		push_back(e);
		}
		}
		return *this;
		}*/

		// lt1 = lt4 -现代写法
		list<T>& operator= (list<T> lt)//这里赋值用的是传值
		{
			swap(_head, lt._head);
			return *this;
		}
		//把所有的数据清理掉,但不清理头结点,清理后还可以再插入
		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);
			}
		}
		//尾插
		void push_back(const T& x)
		{
			//Node* tail = _head->_prev;//找尾
			//Node* newnode = new Node(x);
			//tail->_next = newnode;
			//newnode->_prev = tail;
			//newnode->_next = _head;
			//_head->_prev = newnode;
			insert(end(), x);
		}
		//头插
		void push_front(const T& x)
		{
			insert(begin(), x);
		}
		//尾删
		void pop_back()
		{
			erase(--end());
		}
        //头删
		void pop_front()
		{
			erase(begin());
		}
	   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;
			//iterator ret(newnode);
	    	//return ret;
			return iterator(newnode);
			//return newnode;
		}
	   //类模板中的成员函数是按需实例化,调用了哪个成员函数,就实例化哪个
	   //按需实例化--assert不写头文件在普通的erase可能不报错,但是clear调用erase没有头文件就会报错
	   //函数模板
		iterator erase(iterator pos)
		{
			//不能删头结点--end为最后一个节点的下一个数据即头结点
			assert(pos != end());
			Node* cur = pos._node;
			//找到要删节点的前后节点,然后再删除此节点,此节点的前后节点连接即可
			Node* prev = cur->_prev;
			Node* next = cur->_next;
			delete cur;
			prev->_next = next;
			next->_prev = prev;
			//follow刚刚被删除那个节点
			return iterator(next);
		}
		//求size--O(n)的接口少使用
		size_t size()
		{
			size_t n = 0;
			iterator it = begin();
			while (it != end())
			{
				++it;
				++n;
			}
			return n;
		}
		bool empty()
		{
			return begin() == end();//head->next=head
		}
	private:
		Node* _head;
	};
	//需要const迭代器--const对象
	void print_list(const list<int>& l)
	{
		list<int>::const_iterator it = l.begin();
		while (it != l.end())
		{
			//*it += 1;--err,const迭代器的不能修改
			cout << *it << " ";
			++it;
		}
		cout << endl;
	  }
	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.operator*() = 10;
			//*it = 10;
			cout << *it << " ";
			++it;
		}
		cout << endl;
		for (auto e : lt)
		{
			cout << e << " ";
		}
		cout << endl;
	}
    //树--自定义类型
	struct TreeNode
	{
		struct TreeNode* _left;
		struct TreeNode* _right;
		int _val;

		TreeNode(int val = -1)
			:_left(nullptr)
			, _right(nullptr)
			, _val(val)
		{}
	};
	//ostream& operator<<(ostream& out, TreeNode n);
	void test_list2()
	{
		list<TreeNode> lt;
		lt.push_back(TreeNode(1));
		lt.push_back(TreeNode(2));
		lt.push_back(TreeNode(3));
		lt.push_back(TreeNode(4));

		list<TreeNode>::iterator it = lt.begin();
		while (it != lt.end())
		{
			//cout << (*it)._val << " ";
			//结构体打印的方法-->用点,(*it)即it.Operator*()
			printf("val:%d,left:%p,right:%p\n", (*it)._val, (*it)._left, (*it)._right);
			//在前面重载Operator->就能使用,返回的是operator的指针,重载operator->用的是Ptr,ptr对应的是T*所以返回的是指针
			printf("val:%d,left:%p,right:%p\n", it->_val, it->_left, it->_right);
			++it;
		}
		cout << endl;
	}
	void test_list3()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);

		print_list(lt);
		lt.clear();
		print_list(lt);

		lt.push_back(10);
		lt.push_back(20);
		lt.push_back(30);
		print_list(lt);
	}
	void test_list4()
	{
		list<int> lt1;
		lt1.push_back(1);
		lt1.push_back(2);
		lt1.push_back(3);
		lt1.push_back(4);
		for (auto e : lt1)
		{
			cout << e << " ";
		}
		cout << endl;
		list<int> lt2(lt1);
		for (auto e : lt2)
		{
			cout << e << " ";
		}
		cout << endl;
		//拷贝构造
		list<int> lt3(lt1.begin(), lt1.end());
		for (auto e : lt3)
		{
			cout << e << " ";
		}
		cout << endl;
		string s("hello");
		list<int> lt4(s.begin(), s.end());
		for (auto e : lt4)
		{
			cout << e << " ";
		}
		cout << endl;
		//赋值
		lt1 = lt4;
		for (auto e : lt1)
		{
			cout << e << " ";
		}
		cout << endl;
	}
	// int* p       *p
	// TreeNode* p  p->_val
}

test.c

#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <functional>
#include <time.h>
using namespace std;
#include "List.h"
int main()
{
	bit::test_list1();
	//bit::test_list2();
	//bit::test_list3();
	//bit::test_list4();
	return 0;
}

insert

在这里插入图片描述

迭代器

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

迭代器需不需要实现析构、拷贝构造、赋值重载

  • 不需要默认生成就好了
  • 因为节点属于链表的,不是迭代器的,节点不需要迭代器来析构,而是链表自己析构
  • 默认为浅拷贝

Test_List1()

在这里插入图片描述

Test_List2()

在这里插入图片描述
在这里插入图片描述

Test_List3()

在这里插入图片描述

Test_List4()

  • 迭代器默认为浅拷贝,但是list得自己写深拷贝不然会因为浅拷贝而报错
    在这里插入图片描述
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值