返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++之list容器模拟实现方式
  • 900
分享到

C++之list容器模拟实现方式

C++list容器list容器模拟实现模拟实现list 2023-02-05 15:02:31 900人浏览 泡泡鱼
摘要

目录总述一、节点类二、迭代器类成员变量构造函数*重载->重载“++”“==“和”!=”三、反向迭代器类成

总述

list模拟实现主要包括四个类:节点类、迭代器类、反向迭代器类、list类

list底层结构:

因为list的底层空间不连续,所以迭代器不能使用原生态的指针,将节点类型的指针封装成类,重载解引用及自增等常用操作。list可以保存多种数据类型,所以这些类都写成类模板

一、节点类

list底层是带头结点的双向循环链表,先实现节点类,给成类模板的形式,便于插入不同类型的数据。

template<class T>
struct Listnode
{
	ListNode<T>* prev;
	ListNode<T>* next;
	T data;//要在链表中保存的数据类型

	ListNode(const T& value = T())
		:prev(nullptr)
		, next(nullptr)
		, data(value)
	{ }
};

定义新节点的方法:

ListNode<变量类型>*变量名=new ListNode(value);

二、迭代器类

迭代器类模板有三个参数

  • T:迭代器指向的元素类型
  • Ref:返回的引用类型
  • Ptr:返回的指针类型

Ref和Ptr一般不写成T&和T*。

成员变量

迭代器类的成员变量就是节点类型的指针

Node* _pNode;//成员变量,节点类型指针

构造函数

编译器默认的构造函数是无参的,构造函数需要给出

ListIterator(Node* pNode = nullptr)
	:_pNode(pNode)
{}

*重载

返回节点中保存的数据

Ref operator*()
{
	return _pNode->data;
}

->重载

返回节点中保存的数据的地址

Ptr operator->()
{
	return &_pNode->data;
}

->的重载只对内置类型有意义:

“++”

前置++

返回值是迭代器自身类型的引用,前面已经将ListIterator<T, Ref, Ptr>重命名位Self,表示迭代器自身的类型。

Self& operator++()
{
	_pNode = _pNode->next;
	return *this;
}

后置++

定义临时变量,返回自增前的值

Self operator++(int)
{
	Self temp(*this);
	_pNode = _pNode->next;
	return temp;
}

“–”

与++原理相同

Self& operator--()
{
	_pNode = _pNode->prev;
	return (*this);
}
Self operator--(int)
{
	Self temp(*this);
	_pNode = _pNode->prev;
	return temp;
}

“==“和”!=”

比较两个迭代器中封装的指针

bool operator!=(const Self& it)
{
	return _pNode != it._pNode;
}
bool operator==(const Self& it)
{
	return _pNode == it._pNode;
}

三、反向迭代器类

反向迭代器可以对迭代器类进行复用

因为类外访问静态成员变量时也会使用类名::变量名的方式,所以对迭代器类中的Reference和Pointer进行重命名时要加上typename,明确告诉编译器要重命名的是一个数据类型。否则编译器会报错:

成员变量

反向迭代器对迭代器类进行复用

private:
	Iterator _it;//正向迭代器

*重载

反向迭代器的解引用要做特殊处理,返回的是对迭代器–的值

Reference operator*()
{
	/
		    //复用insert
			insert(begin(), value);
		}
		void pop_front()
		{
			erase(begin());
		}

		//⭐insert
		// iterator是ListIterator<T, T&, T*>
		iterator insert(iterator Insertpos, const T& value)
		{
			Node* newnode = new Node(value);
			Node* pos = Insertpos._pNode;//_pNode是节点类型的指针
			newnode->next = pos;
			newnode->prev = pos->prev;
			newnode->prev->next = newnode;
			pos->prev = newnode;
			//return newnode;
			//⭐迭代器是封装的Node*指针,此时不能再返回newnode
			return iterator(newnode);//构造匿名对象返回
		}
		//⭐erase
		iterator erase(iterator Erasepos)
		{
			Node* pos = Erasepos._pNode;
			Node* ret = pos->next;
			pos->prev->next = pos->next;
			pos->next->prev = pos->prev;
			delete pos;
			return iterator(ret);
		}
		iterator erase(iterator first, iterator last)
		{
			auto it = first;
			while (it != last)
			{
				//it=erase(it);
				erase(it++);
			}
			return it;
		}

		void clear()
		{
			erase(begin(), end());
		}
		void swap(list<T>& l)
		{
			std::swap(head, l.head);
		}

	private:
		//提供一个创造头结点的方法
		void CreatHead()
		{
			//调用节点类的构造方法
			head = new Node();
			head->next = head;
			head->prev = head;
		}
	private:
		Node* head;

	};

	template<class T>
	void PrintList(const list<T>& l)
	{
		auto it = l.cbegin();
		while (it != l.cend())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
	}
}

void Test1()
{
	ZH::list<int> l1;
	ZH::list<int> l2(3, 1);
	PrintList(l2);
	ZH::list<int> l3(l2.begin(), l2.end());
	PrintList(l3);
	vector<int> v{ 0,1,2,3,4 };
	ZH::list<int> l4(v.begin(), v.end());
	PrintList(l4);
}

void Test2()
{
	vector<int> v{ 1,2,3,4 };
	ZH::list<int> L1(v.begin(), v.end());
	L1.push_back(5);
	L1.push_back(6);
	L1.push_front(0);
	PrintList(L1);
	L1.pop_back();
	L1.pop_front();
	PrintList(L1);
	L1.erase(--L1.end());
	PrintList(L1);
}

void Test3()
{
	ZH::list<int> L1;
	L1.push_back(1);
	L1.push_back(2);
	L1.push_back(3);
	L1.push_front(0);
	PrintList(L1);
	L1.resize(6, 5);
	PrintList(L1);
}

struct A
{
	int a;
	int b;
	int c;
};

void Test4()
{
	A aa{ 1,2,3 };
	A bb{ 4,5,6 };
	A cc{ 7,8,9 };
	ZH::list<A> L;
	L.push_back(aa);
	L.push_back(bb);
	L.push_back(cc);
	auto it = L.begin();
	while (it != L.end())
	{
		//⭐it->得到的是节点的地址
		//本应是it->->a,编译器做了特殊处理
		cout << it->a << " ";
		it++;
	}
	cout << endl;
}

void Test5()
{
	ZH::list<int> L1;
	L1.push_back(0);
	L1.push_back(1);
	L1.push_back(2);
	L1.push_back(3);
	PrintList(L1);
	cout << L1.back() << endl;
	cout << L1.front() << endl;
	cout << L1.size() << endl;
	L1.clear();
	cout << L1.size() << endl;
}
 void Test6()
 {
	 ZH::list<int> L1;
	 L1.push_back(0);
	 L1.push_back(1);
	 L1.push_back(2);
	 L1.push_back(3);
	 PrintList(L1);
	 //区间删除
	 

	 ZH::list<int> L2;
	 L2.push_back(1);
	 L2.push_back(2);
	 L2.push_back(3);
	 L2.push_back(4);
	 L2.push_back(5);
	 PrintList(L2);
	 L1.swap(L2);
	 PrintList(L1);
	 PrintList(L2);
 }

int main()
{
	Test6();
	system("pause");
	return 0;
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: C++之list容器模拟实现方式

本文链接: https://lsjlt.com/news/194251.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++之list容器模拟实现方式
    目录总述一、节点类二、迭代器类成员变量构造函数*重载->重载“++”“==“和”!=”三、反向迭代器类成...
    99+
    2023-02-05
    C++ list容器 list容器模拟实现 模拟实现list
  • C++之list容器模拟怎么实现
    这篇“C++之list容器模拟怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++之list容器模拟怎么实现”文章吧...
    99+
    2023-07-05
  • 利用C++模拟实现STL容器:list
    目录一、list的介绍二、list的排序三、迭代器1、list的迭代器失效问题2、迭代器的功能分类3、list迭代器的模拟实现4、迭代器价值5、迭代器operator->的重载...
    99+
    2022-12-08
    C++实现STL容器list C++ STL容器list C++ STL容器
  • C++list的模拟实现
    目录一、节点的结构,list的迭代器的结构,以及list的结构1、节点的结构2、迭代器的结构3、list的结构二、迭代器的实现1、*运算符重载2、++ 与 --运算符3、->运...
    99+
    2023-05-16
    C++ list C++ list模拟实现
  • C++模拟实现list功能
    目录list介绍构造函数无参构造函数有参构造函数模板区间构造函数拷贝构造函数赋值运算符重载析构函数迭代器迭代器构造函数迭代器关系运算符重载迭代器++ --运算符重载迭代器 * 运算符...
    99+
    2024-04-02
  • C++之list容器介绍及使用方式
    目录一、list底层结构二、构造方法构造函数拷贝构造函数三、元素访问和迭代器back&front三种遍历方式四、元素修改尾插、头插、尾删、头删insert、eraseswap...
    99+
    2023-02-05
    C++ list容器 list容器介绍 list容器使用
  • C++模拟实现List迭代器详解
    目录概念迭代器使用迭代器模拟实现迭代器的大体结构构造函数解引用重载重载自增实现自减实现运算符重载迭代器失效模拟List概念 迭代器是一种抽象的设计概念,其定义为:提供一种方法,使他能...
    99+
    2024-04-02
  • 详解C++ STL模拟实现list
    目录list 概述接口总览list 的节点默认成员函数默认构造函数析构函数拷贝构造函数复制赋值函数list 的迭代器构造函数operator==operator!=operator*...
    99+
    2023-01-11
    C++ STL实现list C++ STL list
  • C++初阶之list的模拟实现过程详解
    list的介绍 list的优点: list头部、中间插入不再需要挪动数据,O(1)效率高 list插入数据是新增节点,不需要增容 list的缺点: ...
    99+
    2024-04-02
  • C++中list容器的实现
    目录一、list容器1.1 简介1.2 构造函数1.3 赋值和交换1.4 大小操作1.5 插入和删除1.6 数据存取1.7 反转和排序一、list容器 1.1 简介 ① 功能:将数据...
    99+
    2023-05-13
    C++ list容器
  • C++中list的使用与模拟实现
    目录一、list的介绍以及使用1.1 list的介绍1.2 list的使用1.2.1 list的构造1.2.2 list iterator的使用1.2.3 list capacity...
    99+
    2024-04-02
  • C++深入探究list的模拟实现
    目录迭代器正向迭代器类反向迭代器类push_back尾插函数push_front头插函数insert插入函数erase删除函数pop_front函数pop_back函数构造函数析构函...
    99+
    2024-04-02
  • 怎么用C++模拟实现STL容器
    这篇文章主要介绍了怎么用C++模拟实现STL容器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用C++模拟实现STL容器文章都会有所收获,下面我们一起来看看吧。一、list的介绍列表是一种顺序容器,它允许在...
    99+
    2023-07-04
  • C++ STL容器详解之红黑树部分模拟实现
    目录一、红黑树的概念二、红黑树的性质三、红黑树节点的定义四、红黑树结构 五、 红黑树的插入操作六、代码总结一、红黑树的概念 红黑树(Red Black Tree),是在计算机科学中用...
    99+
    2024-04-02
  • C++中list容器如何实现
    本篇内容介绍了“C++中list容器如何实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、list容器1.1 简介① 功能:将数据进行链...
    99+
    2023-07-05
  • C#设计模式实现之迭代器模式
    目录前言:一、餐馆合并菜单 二、改进菜单实现 三、迭代器模式 总结前言: 迭代器模式平时用的不多,因为不管C#还是Java都已经帮我封装了,但是你是否知道平时经常在用的东西本质是怎么...
    99+
    2024-04-02
  • C++之list容器如何使用
    今天小编给大家分享一下C++之list容器如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、list底层结构list...
    99+
    2023-07-05
  • C++类模板实战之vector容器的实现
    目录案例要求完成步骤1、封装数组类属性并完成有参构造以及析构函数2、提供对应的深拷贝构造函数防止调用析构时出错3、重载类内的赋值运算符防止浅拷贝问题出现4、提供尾部插入和删除的方法5...
    99+
    2024-04-02
  • C#设计模式之适配器模式与装饰器模式的实现
    目录结构型设计模式适配器模式实现代码总结装饰器模式实现代码结构型设计模式 创建型设计模式主要是为了解决创建对象的问题,而结构型设计模式则是为了解决已有对象的使用问题。 适配器模式 适...
    99+
    2024-04-02
  • C#设计模式实现之生成器模式和责任链模式
    目录生成器设计类图: 实现代码:优点:用途与缺点:责任链设计类图:实现代码:优点:用途和缺点:总结生成器 生成器模式:封装一个产品的构造过程,并允许按步骤构造。 现又一个...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作