C++——模拟实现list

1.初步实现结点和链表

namespace jxy
{
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _prev;
		list_node<T>* _next;

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

	template<class T>
	class list//list的框架本质是封装+运算符重载
	{
		typedef list_node<T> Node;

	public:

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

		list()
		{
			empty_init();
		}

	private:
		Node* _head;
		size_t _size;
	};
}

2.push_back

namespace jxy
{
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _prev;
		list_node<T>* _next;

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

	template<class T>
	class list//list的框架本质是封装+运算符重载
	{
		typedef list_node<T> Node;

	public:

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

			_size = 0;
		}

		list()
		{
			empty_init();
		}

		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;
		}

	private:
		Node* _head;
		size_t _size;
	};
}

3.初步实现迭代器

将迭代器封装为类来实现其功能

namespace jxy
{
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _prev;
		list_node<T>* _next;

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

	template<class T>
	struct __list_iterator//一般前加__就说明这是内部的实现
	{
		typedef list_node<T> Node;
		typedef __list_iterator<T> self;
		Node* _node;

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

		self& operator++()//不是连续的物理空间,++不能到下一个位置
		{
			_node = _node->_next;
			return *this;
		}

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

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

	template<class T>
	class list//list的框架本质是封装+运算符重载
	{
		typedef list_node<T> Node;

	public:
		typedef __list_iterator<T> iterator;
		iterator begin()
		{
			//return iterator(_head->_next);
			return _head->_next;
		}

		iterator end()
		{
			//return iterator(_head);
			return _head;
		}

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

		list()
		{
			empty_init();
		}

		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;
		}

	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())
		{
			*it += 10;//还可以修改

			cout << *it << " ";
			++it;
		}
		cout << endl;

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

4.插入和删除

namespace jxy
{
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _prev;
		list_node<T>* _next;

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

	template<class T>
	struct __list_iterator//一般前加__就说明这是内部的实现
	{
		typedef list_node<T> Node;
		typedef __list_iterator<T> self;
		Node* _node;

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

		self& operator++()//不是连续的物理空间,++不能到下一个位置
		{
			_node = _node->_next;
			return *this;
		}

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

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

	template<class T>
	class list//list的框架本质是封装+运算符重载
	{
		typedef list_node<T> Node;

	public:
		typedef __list_iterator<T> iterator;

		void clear()//不清哨兵位的头结点
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);
			}
		}

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

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

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

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

		//void insert(iterator pos,const T& x)
		//{
		//	Node* cur = pos._node;
		//	Node* newnode = new Node(x);

		//	Node* prev = cur->_prev;

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

		//	newnode->_next = cur;
		//	cur->_prev = newnode;

		//	//理论上可以认为list的迭代器不存在失效问题
		//}

		iterator insert(iterator pos, const T& x)
		{
			Node* cur = pos._node;
			Node* newnode = new Node(x);

			Node* prev = cur->_prev;

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

			newnode->_next = cur;
			cur->_prev = newnode;

			++_size;

			return iterator(newnode);//指向新插入的元素
		}

		//void erase(iterator pos)
		//{
		//	Node* cur = pos._node;

		//	Node* prev = cur->_prev;
		//	Node* next = cur->_next;

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

		//}

		iterator erase(iterator pos)
		{
			Node* cur = pos._node;

			Node* prev = cur->_prev;
			Node* next = cur->_next;

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

			--_size;

			//erase后的迭代器会失效,所有最好把返回值类型改为iterator
			return iterator(next);
		}

		size_t size()
		{
			return _size;
		}

	private:
		Node* _head;
		size_t _size;
	};

}

5.拷贝构造和赋值

namespace jxy
{
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _prev;
		list_node<T>* _next;

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

	template<class T>
	struct __list_iterator//一般前加__就说明这是内部的实现
	{
		typedef list_node<T> Node;
		typedef __list_iterator<T> self;
		Node* _node;

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

		self& operator++()//不是连续的物理空间,++不能到下一个位置
		{
			_node = _node->_next;
			return *this;
		}

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

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

	template<class T>
	class list//list的框架本质是封装+运算符重载
	{
		typedef list_node<T> Node;

	public:
		typedef __list_iterator<T> iterator;

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

		iterator end()
		{
			//return iterator(_head);
			return _head;
		}

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

		list()
		{
			empty_init();
		}

		~list()
		{
			clear();

			delete(_head);
			_head = nullptr;
		}

		//拷贝构造
		//list(const list<T>& lt)//这里是const迭代器
		list(list<T>& lt)
		{
			empty_init();
			for (auto e : lt)
			{
				push_back(e);
			}
		}

		传统写法
		//list<int>& operator=(const list<int>& lt)
		//{
		//	if (this != &lt)
		//	{
		//		clear();
		//		for (auto e : lt)
		//		{
		//			push_back(e);
		//		}
		//	}
		//	return *this;
		//}

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

		list<int>& operator=(list<int> lt)//调用拷贝构造
		{
			swap(lt);
			return *this;
		}

	private:
		Node* _head;
		size_t _size;
	};

}

6.完善迭代器

namespace jxy
{
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _prev;
		list_node<T>* _next;

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

	template<class T>
	struct __list_iterator//一般前加__就说明这是内部的实现
	{
		typedef list_node<T> Node;
		typedef __list_iterator<T> self;
		Node* _node;

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

		self& operator++()//不是连续的物理空间,++不能到下一个位置
		{
			_node = _node->_next;
			return *this;
		}

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

		//自定义类型尽量使用前置++,后置++要返回++之前的值
		self operator++(int)
		{
			self tmp(*this);

			_node = _node->_next;
			return tmp;
		}

		self operator--(int)
		{
			self tmp(*this);

			_node = _node->_prev;
			return tmp;
		}

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

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

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

		//迭代器不需要析构函数
		//它虽然有结点的指针,但是指针是不属于它的,它不能释放

		//迭代器的拷贝构造和赋值也不需要去实现深拷贝
	};

	template<class T>
	class list
	{
		typedef list_node<T> Node;

	public:

	private:
		Node* _head;
		size_t _size;
	};

}

7.补充:迭代器的->运算符重载

namespace jxy
{
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _prev;
		list_node<T>* _next;

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

	template<class T>
	struct __list_iterator//一般前加__就说明这是内部的实现
	{
		typedef list_node<T> Node;
		typedef __list_iterator<T> self;
		Node* _node;

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

		self& operator++()//不是连续的物理空间,++不能到下一个位置
		{
			_node = _node->_next;
			return *this;
		}

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

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

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

	template<class T>
	class list
	{
		typedef list_node<T> Node;

	public:

	private:
		Node* _head;
		size_t _size;
	};

	void test_list3()
	{//存一个自定义类型
		list<AA> lt;
		lt.push_back(AA(1, 2));
		lt.push_back(AA(2, 3));
		lt.push_back(AA(3, 4));

		list<AA>::iterator it = lt.begin();
		while (it != lt.end())
		{
			//cout << *it << " ";//*it的类型是AA,不支持流插入

			//一、让AA类支持流插入

			//二、打印公有成员变量
			//cout << (*it)._a1 << " " << (*it)._a2 << endl;

			//三、让AA类支持->
		    //自定义类型不支持运算符,需要重载
			cout << it->_a1 << " " << it->_a2 << endl;
			cout << it.operator->()->_a1 << " " << it.operator->()->_a2 << endl;

			++it;

			//当数据存储自定义类型时,重载->
		}

		//解引用有三种方式:*、[]、->
		int* p = new int;
		*p = 1;

		AA* ptr = new AA;
		ptr->_a1=1;
	}

}

8.const迭代器

namespace jxy
{
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _prev;
		list_node<T>* _next;

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


    //const迭代器模拟的是指向的内容不能改变,而不是本身不能改变
    //const迭代器本身可以++
	template<class T>
	struct __list_const_iterator//const迭代器是一个单独的类
	{
		typedef list_node<T> Node;
		typedef __list_const_iterator<T> self;
		Node* _node;

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

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

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

		self operator++(int)
		{
			self tmp(*this);

			_node = _node->_next;
			return tmp;
		}

		self operator--(int)
		{
			self tmp(*this);

			_node = _node->_prev;
			return tmp;
		}

		const T& operator*() //通过解引用才能修改数据
		{
			return _node->_data;//返回的是const别名,不能修改
		}

		const T* operator->()
 		{
			return &_node->_data;
		}

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

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

	template<class T>
	class list//list的框架本质是封装+运算符重载
	{
		typedef list_node<T> Node;

	public:
		typedef __list_iterator<T> iterator;
		typedef __list_const_iterator<T> const_iterator;
		//单独去支持一个类型:const_iterator

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

		const_iterator end() const
		{
			//return const_iterator(_head);
			return _head;
		}

	private:
		Node* _head;
		size_t _size;
	};

    //测试const迭代器
	void print_list(const list<int>& lt)
	{
		list<int>::const_iterator it = lt.begin();
		while (it != lt.end())
		{
			//*it = 100;//不可修改

			cout << *it << " ";
			it++;
		}
		cout << endl;
	}

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

		print_list(lt);
	}
}

9.改善

当前代码的实现太过冗余

引用和提供了关于实现vector的两种方法。其中,引用展示了一个使用reserve和push_back方法的示例,而引用展示了一个使用new和memcpy函数的示例。这两种方法都是常见的实现vector的方式。 在第一种方法中,通过reserve函数可以预留足够的内存空间,然后使用push_back函数逐个将元素添加到vector中。这种方法的好处是可以避免不必要的内存重分配,提高了效率。 而第二种方法使用new操作符在堆上分配内存空间,并使用memcpy函数将已有的vector对象的数据复制到新的内存空间中。通过这种方式,可以实现深拷贝,即两个vector对象拥有独立的内存空间。这种方法的好处是可以在不修改原始vector对象的情况下创建一个新的vector对象。 除了以上两种方法,还可以使用其他方式实现vector类。例如,可以使用动态数组来实现vector的底层数据结构,然后通过成员函数实现vector的各种操作,如增加、删除、查找等。 总结来说,c语言模拟实现vector的关键是动态内存管理和对元素的增删改查操作。可以使用预留空间和逐个添加元素的方式,也可以使用动态数组和复制数据的方式来实现vector类。具体的实现方式可以根据需求和实际情况选择。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C++——vector模拟实现](https://blog.csdn.net/weixin_49449676/article/details/126813526)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值