【C++之容器篇】造轮子:list的模拟实现与使用

news2024/9/22 15:44:19

目录

    • 前言
    • 一、关于list
      • 1. 简介
      • 2. 成员类型
    • 二、默认成员函数
      • 1. 构造函数
        • 1. list()
        • 2. list(size_t n,const T& val = T())和list(InputIterator first,InputIterator last)
      • 2. 拷贝构造函数
      • 3. 析构函数
      • 4. 赋值运算符重载函数
    • 三、迭代器
      • 1. 普通对象的正向迭代器
      • 2. const对象的正向迭代器
      • 3. 普通对象的反向迭代器
      • 4. const对象的反向迭代器
    • 四、容量接口
      • 1. empty()
      • 2. size()
    • 五、元素访问接口
      • 1. front()
      • 2. back()
    • 六、修改接口
      • 1. push_front()
      • 2. pop_front()
      • 3. push_back()
      • 4. pop_back()
      • 5. insert()
      • 6.erase()

前言

前面我们已经学习了string和vector的模拟实现和使用,相信对于容器的模拟实现和使用的能力已经上升一定的水平,今天我们要学习的是list的模拟实现,List的模拟实现和string和vector其实没有本质的区别,只是在list的模拟实现过程中,list的迭代器和string和vector有所不同,这是我们实现List的模拟实现中需要重点掌握的,今天学习的List本质就是一个带头双向循环链表。

一、关于list

1. 简介

在这里插入图片描述
list本质就是一个带头双向循环链表,支持在任何位置以O(1)的时间进行插入和删除。

2. 成员类型

在这里插入图片描述
看到上图,我们一定要知道迭代器的类型:list中的迭代器的类型是双向迭代器,其他的迭代器类型好还有:单向迭代器,随机迭代器。

  • 单向迭代器:只支持单向遍历访问的迭代器,只支持++,不支持–
  • 双向迭代器:支持双向访问容器的迭代器,同时支持++和–
  • 随机迭代器:支持随机访问容器的迭代器,同时支持++,–,+,-

二、默认成员函数

1. 构造函数

在这里插入图片描述

1. list()

  • 使用代码
void test_list1()
{
	// 无参构造函数
	list<int> lt1;// 创建一个存储int的list对象
	list<char> lt2;// 创建一个存储char的list对象
	list<double> lt3;// 创建一个存储double的list对象
	list<string> lt4;// 创建一个存储string的list对象
}

2. list(size_t n,const T& val = T())和list(InputIterator first,InputIterator last)

  • 使用代码:
void test_list2()
{
	
	// 用n个值来构造List
	list<int> lt1(3, 6);// 用3个6来构造一个list对象

	// 使用一段迭代器区间来构造
	string s2("hello list::list(InputIterator first,InputIterator last)");
	vector<char> v2(s2.begin(), s2.end());
	list<char> lt2(v2.begin(), v2.end());

	// 遍历
	

	// 使用迭代器进行遍历
	// 遍历lt1
	cout << "lt1:" << endl;
	list<int>::iterator lit1 = lt1.begin();
	while (lit1 != lt1.end())
	{
		cout << *lit1 << " ";
		lit1++;
	}
	cout << endl;

	// 遍历lt2
	cout << "lt2:" << endl;
	list<char>::iterator lit2 = lt2.begin();
	while (lit2 != lt2.end())
	{
		cout << *lit2 << " ";
		lit2++;
	}
	cout << endl;

	// 使用范围for进行遍历
	cout << "lt1:" << endl;
	for (auto& e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;

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



}

运行结果:
在这里插入图片描述

2. 拷贝构造函数

在这里插入图片描述
拷贝构造函数和前面的容器样子还是差不多

void test_list3()
{
	string s("hello list(const list<char>& lt)");
	list<char> lt1(s.begin(), s.end());
	list<char> lt2(lt1);

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

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

运行结果:
在这里插入图片描述

3. 析构函数

4. 赋值运算符重载函数

在这里插入图片描述

  • 使用代码:
void test_list4()
{
	string s("hello list<char>& operator=(const list<char>& lt)");
	list<char> lt(s.begin(), s.end());
	list<char> lt1;
	lt1 = lt;// 调用赋值运算符重载函数

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

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

}

运行结果:

在这里插入图片描述

三、迭代器

1. 普通对象的正向迭代器

  • 使用代码:
void test_list5()
{
	string s("hello list<char>::iterator begin() and end()");
	list<char> lt(s.begin(), s.end());

	list<char>::iterator lit = lt.begin();
	while (lit != lt.end())
	{
		cout << *lit << " ";
		lit++;
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

2. const对象的正向迭代器

  • 使用代码:
void test_list6()
{
	string s("hello list<char>::const_iterator begin() and end()");
	const list<char> lt(s.begin(), s.end());

	list<char>::const_iterator lit = lt.begin();
	while (lit != lt.end())
	{
		cout << *lit << " ";
		lit++;
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

3. 普通对象的反向迭代器

使用代码:

void test_list7()
{
	string s("hello list<char>::reverse_iterator begin() and end()");
	list<char> lt(s.begin(), s.end());

	list<char>::reverse_iterator lit = lt.rbegin();
	while (lit != lt.rend())
	{
		cout << *lit << " ";
		lit++;
	}
	cout << endl;
}

4. const对象的反向迭代器

四、容量接口

1. empty()

2. size()

五、元素访问接口

1. front()

2. back()

六、修改接口

1. push_front()

2. pop_front()

3. push_back()

4. pop_back()

5. insert()

6.erase()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/341614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多线程

标题创建多线程方式一&#xff1a;继承线程中常用方法和优先级多窗口卖票创建多线程方式二&#xff1a;实现Runnable接口多窗口卖票&#xff08;使用Runable方式&#xff09;进程的生命周期同步代码块解决实现Runable的线程安全问题方法一方法二使用同步方法处理实现Runable的线…

结构体熟练掌握--实现通讯录

魔王的介绍&#xff1a;&#x1f636;‍&#x1f32b;️一名双非本科大一小白。魔王的目标&#xff1a;&#x1f92f;努力赶上周围卷王的脚步。魔王的主页&#xff1a;&#x1f525;&#x1f525;&#x1f525;大魔王.&#x1f525;&#x1f525;&#x1f525; ❤️‍&#x1…

帮助中心在线制作工具推荐这4款,很不错哟!

根据用户咨询问题是否解决的情景&#xff0c;分为三个部分&#xff0c;首先帮助中心恰好有用户需要咨询的问题&#xff0c;用户可以通过点击相关问题即可解决自己的问题&#xff0c;其次&#xff0c;用户第一眼没有在帮助中心解决问题&#xff0c;有个搜索框&#xff0c;用户的…

为什么开发人员应该在 2023 年学习 Docker 和 Kubernetes

开发者你好&#xff0c;如果你想在 2023 年学习新的工具和技术&#xff0c;那么你应该考虑学习 Docker 和 Kubernetes&#xff0c;这是在这个微服务和云计算时代创建和管理容器的两个最重要的工具。随着微服务和云计算的兴起&#xff0c;Docker 和 Kubernetes 已经成为软件开发…

gg又来深圳

我们都喜欢的DGGgg是我在TCL的朋友&#xff0c;刚毕业的我们在TCL度过了一段非常欢快的时光&#xff0c;gg也是我们几十人中在TCL呆的特别久的&#xff0c;先是在深圳&#xff0c;然后转去了惠州&#xff0c;后面在惠州买房、结婚、定居、生娃。前几年举家回了西安、也从TCL离职…

ChatGPT到底是个啥 - 它甚至会和狗说话

写在前面&#xff1a;博主是一只经过实战开发历练后投身培训事业的“小山猪”&#xff0c;昵称取自动画片《狮子王》中的“彭彭”&#xff0c;总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域&#xff0c;如今终有小成…

2023.2.12(总结)

今天主要就是下午进行了一个测试&#xff0c;有三个困难版的题目我没有写出来&#xff0c;打算今天晚上好好磨磨&#xff0c;这里主要就只放一个题目。 C - Don’t be cycle Editorial / Time Limit: 2 sec / Memory Limit: 1024 MB Score : 300300 points Problem Statemen…

Spring缓存指定Redis做为缓存中间件Demo笔记

文档地址D:/Test10/redisdemo和springcachedemo E:/FTPshangchuang/smbms 一下是SpringBoot整合Redis的初略配置,引入Redis依赖 想自己测试的话 链接&#xff1a;https://pan.baidu.com/s/14hdBzdjtFu0lYmZUhy_DuA 提取码&#xff1a;j0m8 Redis配置文件 package com…

总览 Java 容器--集合框架的体系结构

前言 我们在讲 Java 的数据类型的时候&#xff0c;单独介绍过数组&#xff0c;数组也确实是开发程序中常用的内存类型之一&#xff0c;不过 Java 内置的数组限制颇多&#xff0c;所以此后扩展出了List这种结构&#xff0c;与之类似的Set、Queue 这些内存中的容器都被放在了 Co…

浅谈明暗水印

前言 水印&#xff08;Watermark&#xff09;是一种能让人识别纸上图案的技术&#xff0c;当光线照射纸张时&#xff0c;纸张上会显现出各种不同阴影&#xff0c;这些阴影组成的图案就是水印。 水印常常起到验证货币、护照、邮票、政府文件或者其他纸制文件的真实性的作用。 …

什么是热迁移?90%的企业都理解错误

科技的发展&#xff0c;新冠的冲击&#xff0c;让市场竞争愈发激烈。尽管云计算服务为企业免除了基础硬件的建设和维护成本&#xff0c;当企业需要进行业务跨架调整、升级维护、环境测试等场景而进行云迁移&#xff0c;其过程中所带来的停机时间&#xff0c;就变得尤为头疼了。…

清亡之路(4):最受误解的东南互保

很多人一提“东南互保”&#xff0c;就认为是东南是在反叛。如果仔细看&#xff0c;其实根本谈不上造反&#xff0c;反而是更像是一种“遵旨行事”。本文就是说说这个问题。宣战是来真的吗&#xff1f;1900年6月21日&#xff0c;慈禧忍无可忍&#xff0c;决定和各公使馆翻脸&am…

给你的边框加点渐变

目录前言border-imageborder-image实现background父子divbackgorund一个div一个伪元素background-clip&#x1f9e8;&#x1f9e8;&#x1f9e8; 大家好&#xff0c;我是搞前端的半夏 &#x1f9d1;&#xff0c;一个热爱写文的前端工程师 &#x1f4bb;. 如果喜欢我的文章&…

spring cloud

文章目录 目录 文章目录 前言 一、spring cloud 二、ribbon负载均衡 三、openfeign 总结 前言 微服务就是一种将一个单一应用程序拆分为一组小型服务的方法&#xff0c;拆分完成后&#xff0c;每一个服务都运行在独立的进程中&#xff0c;服务于服务之间采用轻量级的通信机制来…

我不允许你还不知道CSS的filter的drop-shadow阴影用法以及与box-shadow的区别详解

这里有两个图片的阴影&#xff0c;你觉得哪个好看&#xff1f; 一个是使用box-shadow另一个是使用filter: drop-shadow 一、我们来了解一下CSS的filter&#xff08;过滤器&#xff09; 该CSS的filter属性可以实现很多效果 &#xff08;一&#xff09;filter: blur(5px) // 高…

Elasticsearch索引库和文档的相关操作

前言&#xff1a;最近一直在复习Elasticsearch相关的知识&#xff0c;公司搜索相关的技术用到了这个&#xff0c;用公司电脑配了环境&#xff0c;借鉴网上的课程进行了总结。希望能够加深自己的印象以及帮助到其他的小伙伴儿们&#x1f609;&#x1f609;。 如果文章有什么需要…

if从入门到出轨

if从入门到出轨(java版本) 为什么会产生很多if分支 在我们的日常生活中,会遇到很多判断逻辑,屁如,如果你在2月14号,心情很好,那么就给女朋友买了个iPhone 14 Pro Max 1TB 银白色,如果你女朋友在2月14号没有收到您老人家的礼物,那么你可能睡沙发或者轨搓衣板,或者直接和其他帅…

【Kafka】【十九】新消费组的消费offset规则

新消费组的消费offset规则 新消费组中的消费者在启动以后&#xff0c;默认会从当前分区的最后⼀条消息的offset1开始消费&#xff08;消费新消息&#xff09;。可以通过以下的设置&#xff0c;让新的消费者第⼀次从头开始消费。之后开始消费新消息&#xff08;最后消费的位置的…

电脑分盘怎么合并?只需1分钟,轻松学会

有些小伙伴喜欢将电脑进行分盘&#xff0c;以此将文件放进不同的分盘进行管理。但有时候&#xff0c;电脑磁盘分盘过多&#xff0c;管理起来又会有些麻烦。将一些闲置的磁盘进行合并很有必要。电脑分盘怎么合并&#xff1f;下面就跟着小编一起来看看吧。 电脑分盘怎么合并&…

Java 变量和数据类型,超详细整理,适合新手入门

目录 一、什么是变量&#xff1f; 二、变量 变量值互换 三、基本数据类型 1、八种基本数据类型 2、布尔值 3、字符串 四、从控制台输入 一、什么是变量&#xff1f; 变量是一种存储值的容器&#xff0c;它可以在程序的不同部分之间共享&#xff1b;变量可以存储数字、字…