c++:stl中list的模拟实现

Posted mbf330

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++:stl中list的模拟实现相关的知识,希望对你有一定的参考价值。

文章目录

list

1、list的介绍及使用

(1)list的介绍/特点

  1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
  2. list的底层是带头双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。
  3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。
  4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。
  5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)。

(2)list的使用/接口介绍

介绍部分常用接口
iterator迭代器
1.begin:返回第一个元素的迭代器
2.end:返回最后一个元素下一个位置的迭代器
3.rbegin:返回第一个元素的reverse_iterator,即end位置
4.rend:返回最后一个元素下一个位置的reverse_iterator,即begin位置
capacity容量
5.empty:检测list是否为空,是返回true,否则返回false
6.size:返回list中有效节点的个数
element access元素访问
7.front:返回list的第一个节点中值的引用
8.back:返回list的最后一个节点中值的引用
modifiers调节器
9.push_front:在list首元素前插入值为val的元素
10.pop_front;删除list中第一个元素
11.push_back:在list尾部插入值为val的元素
12.pop_back:删除list中最后一个元素
13.insert:在list pos位置中插入值为val的元素
14.erase:删除list pos位置的元素
15.swap:交换两个list中的元素
16.clear:清空list中的有效元素

2.list的模拟实现

(1)代码实现

#pragma once
#include <iostream>
#include <list>
#include <algorithm>
#include <assert.h>
using namespace std;

namespace L

	template<class T>
	struct ListNode
	
		T _data;
		ListNode<T>* _next;
		ListNode<T>* _prev;
		//构造函数:初始化节点
		ListNode(const T& x = T())
			: _data(x)
			, _next(nullptr)
			, _prev(nullptr)
		
	;
	//template<class T>
	//迭代器iterator实现
	//用struct实现:定义为公有,不必用友元函数进行调用
	//Ref传T&(引用),Ptr传T*(指针)
	template<class T, class Ref, class Ptr>
	struct List_iterator
	
		typedef ListNode<T> node;
		typedef List_iterator<T, Ref, Ptr> self;
		node* _node;

		List_iterator(node* node)
			:_node(node)
		
		bool operator!=(const self& s) const
		
			return _node != s._node;
		
		bool operator==(const self& s) const
		
			return !(*this != s);
		
		//T*
		Ptr operator->() const
		
			return &_node->_data;    
		
		//T&
		Ref operator*() const
		
			return _node->_data;
		
		// 后置++:it++  it.operator(&it, 0)
		self operator++(int)
		
			self tmp(*this);
			_node = _node->_next;
			return tmp;
		
		// 前置++:++it it.operator(&it)
		self& operator++()
		
			_node = _node->_next;
			return *this;
		
		// 后置--:it--
		self operator--(int)
		
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		
		//前置--:--it;
		self& operator--()
		
			_node = _node->_prev;
			return *this;
		
	;
	
	template<class T>
	class list
	
		typedef ListNode<T> node;
	private:
		//双向带头循环list,
		node* _head;
	public:
		typedef List_iterator<T, T&, T*> iterator;
		typedef List_iterator<T, const T&, const T*> const_iterator;
		//析构:清除数据后置为nullptr
		~list()
		
			clear();
			delete _head;
			_head = nullptr;
		
		//
		void clear()
		
			iterator it = begin();
			while (it != end())
			
				erase(it++);
			
		
		iterator begin()
		
			return _head->_next;
		
		iterator end()
		
			return _head;
		
		const_iterator begin() const
		
			return _head->_next;
		
		const_iterator end() const
		
			return _head;
		
		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;
			list<T> tmp(lt.begin(), lt.end());
			std::swap(_head, tmp._head);
		
		//lt1 = lt2:赋值:交换头节点即可,之后访问的便是另外一个list
		list<T>& operator=(list<T> lt)
		
			std::swap(_head, lt._head);
			return *this;
		
		//拷贝构造函数普通实现
		/*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
		list()
		
			_head = new node;
			_head->_next = _head;
			_head->_prev = _head;
		
		
		//插入  
		iterator insert(iterator pos, const T& x)
		
			node* newnode = new node(x);
			node* cur = pos._node;
			node* prev = cur->_prev;
			//顺序:prev newnode cur
			prev->_next = newnode;
			newnode->_prev = prev;
			cur->_prev = newnode;
			newnode->_next = cur;
			return iterator(newnode);
		
		//删除节点
		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;
			return iterator(next);
		
		//尾插:普通实现&&用insert以及end的迭代器实现
		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(end(), x);
		
		//头插:用insert以及begin的迭代器实现
		void push_front(const T& x)
		
			insert(begin(), x);
		
		//头删:用erase以及begin的迭代器实现
		void pop_front()
		
			erase(begin());
		
		//尾删:用erase以及end的迭代器实现
		void pop_back()
		
			erase(end());
		
	;

(2)测试用例

#include "stlList.h"
namespace L

    struct point
    
        int x;
        int y;
    ; 
    void Test1()
    
        cout << "Test1" << endl;
        list<int> lt;
        lt.push_back(0);
        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.pop_back();
        lt.pop_front();
        list<int> copy = lt;
        for (auto e : copy)
        
            cout << e << " ";
        
        cout << endl;
    
    void Test2()
    
        cout << "Test2" << endl;
        
        list<point> lt;
        lt.push_back( 1,1 );
        lt.push_back( 2,2 );
        lt.push_back( 3,3 );
        lt.push_front( 0,0 );
        list<point>::iterator it = lt.begin();
        while (it != lt.end())
        
            //it->operator()->x;it->operator()->y;
            cout << "(" << it->x << "," << it->y << ")" << " ";
            it++;
        
        cout << endl;
    
    void Test3()
    
        cout << "Test3" << endl;

        list<int> lt;
        lt.push_back(0);
        lt.push_back(1);
        lt.push_back(2);
        lt.push_back(3);
        lt.push_back(4);
        lt.push_back(5);
        //拷贝构造函数测试
        list<int> copy = lt;
        for (auto e : lt)
        
            cout << e << " ";
        
        cout << endl;
    

int main()

    L::Test1();
    L::Test2();
    L::Test3();

    return 0;

(3)运行截图

以上是关于c++:stl中list的模拟实现的主要内容,如果未能解决你的问题,请参考以下文章

C++ STL 中 remove 和 erase 的区别

C++ STL 中 remove 和 erase 的区别

C++STL:list的使用及模拟实现

C++STL:list的使用及模拟实现

C++从青铜到王者第十三篇:STL之list类的模拟实现

C++初阶:STL —— listlist的介绍及使用 | list的深度剖析及模拟实现 | list与vector的对比