STL02——手写简单版本的list
手写一个简单版本的list
设计一个名为 List 的 List 类,该类具有以下功能和特性:
1、基础成员函数
- 构造函数:初始化 List 实例
- 析构函数:清理资源,确保无内存泄露
2、核心功能
- 在 List 末尾添加元素
- 在 List 开头添加元素
- 获取 List 中节点的数量
- 删除 List 末尾的元素
- 删除 List 开头的元素
- 删除 List 中指定值的节点
3、迭代与遍历
- 打印链表中的元素
4、辅助功能
- 重载[]运算符以对链表进行索引访问
- 重载<<运算符以打印链表
输入描述
题目的包含多行输入,第一行为正整数 N, 代表后续有 N 行命令序列。
接下来 N 行,每行包含一个命令,命令格式为 [operation] [parameters] ,具体命令如下:
push_back 命令:
- 格式:push_back [value]
- 功能:在链表末尾添加值为 value 的元素
push_front 命令:
- 格式:push_front [value]
- 功能:在链表开头添加值为 value 的元素
pop_back 命令:
- 格式:pop_back
- 功能:删除链表末尾的元素
pop_front 命令:
- 格式:pop_front
- 功能:删除链表开头的元素
remove 命令:
- 格式:remove [value]
- 功能:删除链表中值为 value 的元素
clear 命令:
- 格式:clear
- 功能:清空链表
size 命令:
- 格式:size
- 功能:获取链表中节点的数量
get 命令:
- 格式:get [index]
- 功能:获取链表中索引为 index 的节点的值
print 命令:
- 格式:print
- 功能:打印链表中的元素
输出描述
输出为每行命令执行后的结果,具体输出格式如下:
**push_back 命令:**无输出
**push_front 命令:**无输出
**pop_back 命令:**无输出
**pop_front 命令:**无输出
**remove 命令:**无输出
**clear 命令:**无输出
**size 命令:**输出一个整数,独占一行,代表当前 List 中元素的数量
**get 命令:**输出一个整数,独占一行,代表 List 中索引为 index 的元素,如果索引无效,则输出 -1
**print 命令:**按照顺序打印当前 List 包含的所有元素,每个元素后都跟一个空格,打印结果独占一行;如果当前的 vector 为空,则打印 empty
#include <iostream>
#include <stdexcept>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
using namespace std;
template <typename T>
class List
{
public:template<typename L>friend ostream& operator<<(ostream& os, const List<L>& pt);
private://定义链表结点struct Node{T data;Node* next;Node* prev;//含参的默认构造函数Node(const T&value, Node* nextNode = nullptr,Node* prevNode = nullptr){data = value;next = nextNode;prev = prevNode;}};//头尾结点指针Node* head;Node* tail;//结点数量size_t size;public:List(){head = NULL;tail = NULL;size = 0;}~List(){clear();//把链表空间释放}//前插void push_front(const T& value){//创造新节点,next指向的是headNode* newNode = new Node(value, head, NULL);if (head != NULL)//如果链表非空{head->prev = newNode;}else{//如果链表是空的,则首尾都要指向这个独苗tail = newNode;}head = newNode;//头结点前移size++;}//尾插void push_back(const T& value){Node* newNode = new Node(value, NULL, tail);if (tail != NULL)tail->next = newNode;elsehead = newNode;tail = newNode;//尾结点后移size++;//链表长度加1}size_t getSize() const{return size;}//访问:循环index次,然后返回当前结点的值即可T& operator[](size_t index){Node* cur = head;//head相当于是下标为0的元素while (index--){if (cur == NULL)throw out_of_range("index out of range");cur = cur->next;}return cur->data;}const T& operator[](size_t index) const{Node* cur = head;//head相当于是下标为0的元素while (index--){if (cur == NULL)throw out_of_range("index out of range");cur = cur->next;}return cur->data;}//删除链表末尾元素:// 首先直接获取尾结点的前一个结点,// 然后尾结点prev指向null,然后尾结点前移,// 最后将新尾结点的next指向null,size--//void pop_back()//{// if (tail == NULL)// cout << "empty" << endl;// else// {// Node* tailPre = tail->prev;//tailPre可能为空// tail->prev = NULL;// tail = tailPre;// if (tail)// tail->next = NULL;// else// head = NULL;// size--;// } //}//标准(此方法更好,释放了tail的内存,没有造成内存遗失)void pop_back(){if (size > 0){Node* newTail = tail->prev;//直接把尾结点删了,简单粗暴。//结点delete之后,它的prev和next指针都自动消失了delete tail;//虽然空间没了,但是Node*tail这个指针本身还在健在的tail=newTail;if (tail)tail->next = NULL;elsehead = NULL;size--;}}void pop_front(){if (size > 0){Node* newHead = head->next;delete head;head = newHead;if (head)head->prev = NULL;elsetail = NULL;size--;}}Node* getNode(const T& val){//遍历,用whileNode* node = head;while (node!=NULL){if (node->val == val)return node;node = node->next;}return NULL;}//删除结点void remove(const T& val){Node* node = head;while (node != NULL){if (node->data == val){if (node == head && node == tail){node = NULL;}else if (node == head){head = head->next;head->prev = NULL;}else if (node == tail){tail = tail->prev;tail->next = NULL;}else{node->prev->next = node->next;node->next->prev = node->prev;}size--;}node = node->next;}}bool empty(){return size == 0;}void clear(){//每次都设置一个指针指向要被删除的元素while (head!=NULL){Node* node = head;//从头开始head = head->next;//头不断后移delete node;}tail = NULL;size = 0;}Node* begin(){return head;}Node* end(){return NULL;}void printElements() const{Node* node = head;while (node != NULL){cout << node->data << " ";node = node->next;}cout << endl;}};//重载<<运算符
template<typename T>
ostream& operator<<(ostream& os, const List<T>& pt)
{for (typename List<T>::Node* cur = pt.head; cur != NULL; cur = cur->next){os << cur->data << " ";}os << endl;return os;
}int main() {// 创建一个 List 对象List<int> myList;int N;std::cin >> N;// 读走回车getchar();std::string line;// 接收命令for (int i = 0; i < N; i++) {std::getline(std::cin, line);std::istringstream iss(line);std::string command;iss >> command;int value;if (command == "push_back") {iss >> value;myList.push_back(value);}if (command == "push_front") {iss >> value;myList.push_front(value);}if (command == "pop_back") {myList.pop_back();}if (command == "pop_front") {myList.pop_front();}if (command == "remove") {iss >> value;myList.remove(value);}if (command == "clear") {myList.clear();}if (command == "size") {std::cout << myList.getSize() << std::endl;}if (command == "get") {iss >> value;std::cout << myList[value] << std::endl;}if (command == "print") {if (myList.getSize() == 0) {std::cout << "empty" << std::endl;}else {myList.printElements();}}}return 0;
}
相关文章:
STL02——手写简单版本的list
手写一个简单版本的list 设计一个名为 List 的 List 类,该类具有以下功能和特性: 1、基础成员函数 构造函数:初始化 List 实例析构函数:清理资源,确保无内存泄露 2、核心功能 在 List 末尾添加元素在 List 开头添…...
基于SpringBoot的校园自助洗衣服务管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的校园自助洗衣服务…...
音视频入门基础:AAC专题(2)——使用FFmpeg命令生成AAC裸流文件
在文章《音视频入门基础:PCM专题(1)——使用FFmpeg命令生成PCM音频文件并播放》中讲述了生成PCM文件的方法。通过FFmpeg命令可以把该PCM文件转为AAC裸流文件: ./ffmpeg -f s16le -ar 44100 -ac 2 -i audio1.pcm audio1.aac 由于…...
第 6 篇 自定义 Helm Chart
文章目录 第 1 步:创建 chartChart.yamlvalues.yamltemplates 模板文件_helpers.tpl 模板辅助文件serviceaccount.yamlservice.yamldeployment.yamlhpa.yamlingress.yamlNOTES.txttests/test-connection.yaml 第 2 步:检查 chart 格式第 3 步:…...
Jenkis部署vue前端项目提示:sh: vue-cli-service: command not found
解决方法: 1. 进入到/var/lib/jenkins/workspace/项目名下,查看是否有node_modules,如果没有执行 npm install 2. 如果执行npm intall的过程中提示:npm ERR! 407 Proxy Authentication Required - GET http://registry.npm.taob…...
中介者模式mediator
学习笔记,原文链接 https://refactoringguru.cn/design-patterns/mediator 减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。...
GO语言性能分析
Go语言基准测试与pprof工具性能分析详解 在现代软件开发中,性能优化是一个重要的环节。Go语言提供了强大的工具来进行基准测试和性能分析,其中 testing 包用于基准测试,而 pprof 工具用于性能分析。本文将详细讲解如何使用这些工具来进行性能…...
关于 PreparedStatement
Mysql 层面的语法也支持 prepare 这个确实第一次见 PREPARE prepares a statement for execution (see Section 13.5.1, “PREPARE Statement”).EXECUTE executes a prepared statement (see Section 13.5.2, “EXECUTE Statement”).DEALLOCATE PREPARE releases a prepared…...
漫谈设计模式 [9]:外观模式
引导性开场 菜鸟:老鸟,我最近在做一个项目,感觉代码越来越复杂,我都快看不懂了。尤其是有好几个子系统,它们之间的调用关系让我头疼。 老鸟:复杂的代码确实让人头疼。你有没有考虑过使用设计模式来简化你…...
多进程编程
基本概念 进程是一个具有单独功能的程序对某个数据集在处理机上的执行过程,进程也是作为资源分配的一个单位。 进程和程序是相辅相成的,进程是一个动态概念。 进程具有并行性特征。进程具有独立性和异步性。 进程的描述 进程分为三部分:…...
7-Zip压缩包如何添加密码,加密后如何取消
压缩包文件大家经常使用,最熟悉的肯定是RAR、ZIP格式压缩文件,但是7z压缩文件格式也很好用,它是三种压缩文件格式中压缩率最大的。想要将文件压缩到最小,使用7z格式可以达到最大化。那么在使用7z压缩格式的时候,我们可…...
HarmonyOS---应用测试概述
一、应用质量要求 应用质量要求分为应用体验质量建议和应用内容合规要求两大部分。 1、应用体验质量建议 功能数据完备、基础体验要求、HarmonyOS特征增强体验要求。 (1)功能数据完备 (2)基础体验要求 (3)增…...
密码学---真题演练
✨Base加密:题目-base? 靶场网址:https://polarctf.com/ Base100加密!!! 得到的新的一串密码是 rot47 密码,属于凯撒密码的一种变体. ✨斐波那契:题目-FB 从第三项开始,每一项都等…...
时间日期工具类
时间日期工具类 import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit;public class DateTimeUtils {private static final String DEFAULT_DATE_FORMAT "yyyy-MM-dd";private static final String DEFAULT_TIME_…...
linux中vim常用命令大全
前言 Linux有大量的配置文件,所以 Linux的文本处理工具也是比较多的,其中编辑一些配置文件时,常用的工具就是 vim。在Linux中,Vim编辑器是一个非常强大的文本编辑工具,它提供了多种模式和命令来满足不同的编辑需求。以…...
计算机的错误计算(八十九)
摘要 探讨反双曲余切函数 acoth(x) 在 附近的计算精度问题。 Acoth(x) 函数的定义为: 其中 x 的绝对值大于 1 . 例1. 计算 acoth(1.000000000002) . 不妨在 Excel 的单元格中计算,则有: 若在Python中用定义直接计算,则有几乎…...
深入理解java并发编程之aqs框架
跟synchronized 相比较,可重入锁ReentrankLock其实原理有什么不同? 所得基本原理是为了达到一个目的;就是让所有线程都能看到某种标记。synchronized通过在对象头中设置标记实现了这一目的,是一种JVM原生的锁实现方式。而Reentran…...
ubuntu配置tftp、nfs
tftp配置 tftp是简单文件传输协议,基于udp实现传输。这里的简单文件,指的是不复杂、开销不大的文件。 先在ubuntu中安装tftp,输入命令:sudo apt-get install tftp-hpa tftpd-hpa。 接着配置tftp。 输入命令:sudo v…...
Sklearn的datasets模块与自带数据集介绍
datasets 模块 用 dir() 函数查看 datasets 模块的所有属性和函数 import sklearn.datasets as datasets# 列出 sklearn.datasets 模块中的所有属性和函数 print(dir(datasets)) datasets 模块下的数据集有三种类型: (1)load系列的经典数…...
css 个人喜欢的样式 速查笔记
起因, 目的: 记录自己喜欢的, 觉得比较好看的 css. 下次用的时候,直接复制,很方便。 1. 个人 html 模板, 导入常用的 link 设置英语字体: Noto导入默认的 css使用网络 icon 图标导入 Bootstrap css 框架 html <…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
