基于面向对象,C++实现双链表

双链表同单链表类似,由一个值和两个指针组成
在这里插入图片描述

Node.h节点头文件

#pragma once
class Node
{
public:int value;Node* prev;Node* next;Node(int value);~Node();
};

Node.cpp节点源文件

#include "Node.h"Node::Node(int value)
{this->value = value;prev = nullptr;next = nullptr;
}Node::~Node()
{
}

DoubleLinkList.h双链表头文件

#pragma once
#include "Node.h"
class DoubleLinkList
{public:Node* head;Node* tail;int length;DoubleLinkList(int val);//有参构造void PrintDoubleLinkList();//打印双链表void getLength();//获取双链表长度void append(int val);//尾部插入元素void prepend(int val);//头部插入元素void insert(int index, int val);//任意位置插入元素Node* removeLast();//删除最后一个元素Node* removeFirst();//删除第一个元素Node* remove(int index);//删除任意位置元素Node* get(int index);//获取元素bool change(int index, int val);//改变元素int search(int val);//查找元素
};

DoubleLinkList.cpp节点源文件

#include "DoubleLinkList.h"
#include<iostream>
using namespace std;DoubleLinkList::DoubleLinkList(int val)
{Node* newNode = new Node(val);head = newNode;tail = newNode;length = 1;
}//打印链表
void DoubleLinkList::PrintDoubleLinkList()
{Node* temp = head;while (temp!=nullptr) {cout << temp->value << " ";temp = temp->next;}cout << endl;
}
//获取双链表长度
void DoubleLinkList::getLength()
{cout << "双链表长度为:" << length << endl;
}//尾部插入
void DoubleLinkList::append(int val)
{Node* newNode = new Node(val);if (length == 0) {head = newNode;tail = newNode;}else {tail->next = newNode;newNode->prev = tail;tail = newNode;}length++;
}//头部插入
void DoubleLinkList::prepend(int val)
{Node* newNode = new Node(val);if (length == 0) {head = newNode;tail = newNode;}else {newNode->next = head;head->prev = newNode;head = newNode;}length++;
}//任意位置插入
void DoubleLinkList::insert(int index, int val)
{if (index<0 || index>length) {cout << "error";}else if (index == 0) {prepend(val);}else if(index == length){append(val);}else {Node* p1 = head;for (int i = 0; i < index - 1; i++) {p1 = p1->next;}Node* p2 = p1->next;Node* newNode = new Node(val);newNode->prev = p1;newNode->next = p2;p1->next = newNode;p2->prev = newNode;length++;}
}//删除尾部
Node* DoubleLinkList::removeLast()
{if (length == 0) {return nullptr;}Node* temp = tail;if (length == 1) {head = nullptr;tail = nullptr;}else {tail = tail->prev;tail->next = nullptr;temp->prev = nullptr;}length--;return temp;
}//删除头部
Node* DoubleLinkList::removeFirst()
{if (length == 0) {return nullptr;}Node* temp = head;if (length == 1) {head = nullptr;tail = nullptr;}else {head = head->next;head->prev = nullptr;temp->next = nullptr;}length--;return temp;
}//删除任意位置
Node* DoubleLinkList::remove(int index)
{if (index<0 || index>length) {return nullptr;}if (index == 0) {return removeFirst();}if (index == length - 1) {return removeLast();}Node* temp = head;for (int i = 0; i < index; i++) {temp = temp->next;}temp->next->prev = temp->prev;temp->prev->next = temp->next;temp->next = nullptr;temp->prev = nullptr;length--;return temp;
}//获取元素
Node* DoubleLinkList::get(int index)
{if (index<0 || index>length) {return nullptr;}Node* temp = head;if (index < length / 2) {for (int i = 0; i < index; i++) {temp = temp->next;}}else {temp = tail;for (int i = length - 1; i > index; i--) {temp = temp->prev;}}return temp;
}//改变元素
bool DoubleLinkList::change(int index, int val)
{Node* temp = get(index);if (temp) {temp -> value = val;return true;}return false;
}//查找元素
int DoubleLinkList::search(int val)
{int index = 0;Node* temp = head;while (temp->value != val) {index++;temp = temp->next;if (temp == nullptr) {cout << "未找到!" << endl;return -1;}}cout << "找到了!元素索引为:";return index;
}

插入元素

1. 头部插入

1.新节点的next指向head节点
2.head节点的prev指向新节点
3.head移动至新节点
具体如下图所示:

在这里插入图片描述

//头部插入
void DoubleLinkList::prepend(int val)
{Node* newNode = new Node(val);if (length == 0) {head = newNode;tail = newNode;}else {newNode->next = head;head->prev = newNode;head = newNode;}length++;
}

2. 尾部插入

1.尾节点tail的next指向新节点
2.新节点的prev指向尾节点tail
3.tail节点移动到新节点

在这里插入图片描述

//尾部插入
void DoubleLinkList::append(int val)
{Node* newNode = new Node(val);if (length == 0) {head = newNode;tail = newNode;}else {tail->next = newNode;newNode->prev = tail;tail = newNode;}length++;
}

3. 任意位置插入

1.创建新节点p1指向头结点head,然后移动至插入节点前一个节点,并创建新节点p2指向p1的next节点
2.新节点的prev指向p1
3.新节点的next指向p2
4.p1节点的next指向新节点
5.p2节点的prev指向新节点

在这里插入图片描述

//任意位置插入
void DoubleLinkList::insert(int index, int val)
{if (index<0 || index>length) {cout << "error";}else if (index == 0) {prepend(val);}else if(index == length){append(val);}else {Node* p1 = head;for (int i = 0; i < index - 1; i++) {p1 = p1->next;}Node* p2 = p1->next;Node* newNode = new Node(val);newNode->prev = p1;newNode->next = p2;p1->next = newNode;p2->prev = newNode;length++;}
}

删除元素

1. 尾部删除

1.新建一个节点temp指向尾节点tail
2.尾节点tail移动至tail的prev节点
3.尾节点tail的next指向空
4.temp的prev指针指向空

在这里插入图片描述

//删除尾部
Node* DoubleLinkList::removeLast()
{if (length == 0) {return nullptr;}Node* temp = tail;if (length == 1) {head = nullptr;tail = nullptr;}else {tail = tail->prev;tail->next = nullptr;temp->prev = nullptr;}length--;return temp;
}

2. 头部删除

1.新建一个节点temp指向头结点head
2.head节点移动到head的next指针指向的节点
3.head的prev指针指向nullptr
4.temp节点的next指针指向nullptr

在这里插入图片描述

//删除头部
Node* DoubleLinkList::removeFirst()
{if (length == 0) {return nullptr;}Node* temp = head;if (length == 1) {head = nullptr;tail = nullptr;}else {head = head->next;head->prev = nullptr;temp->next = nullptr;}length--;return temp;
}

3. 任意位置删除

1.新建一个节点temp指向头结点head
2.temp移动到要删除的节点处
3.temp的next节点的prev指针指向temp的prev节点
4.temp的prev节点的next指针指向temp的next节点
5.temp的next节点指向nullptr
6.temp的prev节点指向nullptr

在这里插入图片描述

//删除任意位置
Node* DoubleLinkList::remove(int index)
{if (index<0 || index>length) {return nullptr;}if (index == 0) {return removeFirst();}if (index == length - 1) {return removeLast();}Node* temp = head;for (int i = 0; i < index; i++) {temp = temp->next;}temp->next->prev = temp->prev;temp->prev->next = temp->next;temp->next = nullptr;temp->prev = nullptr;length--;return temp;
}

获取元素

1.比较索引和链表长度的大小
2.若索引比length小,则在链表的前一半向后找
3.若索引比length大,则在链表的后一半向前找

在这里插入图片描述

//获取元素
Node* DoubleLinkList::get(int index)
{if (index<0 || index>length) {return nullptr;}Node* temp = head;if (index < length / 2) {for (int i = 0; i < index; i++) {temp = temp->next;}}else {temp = tail;for (int i = length - 1; i > index; i--) {temp = temp->prev;}}return temp;
}

改变元素

1.获取节点
2.将节点的值改为需要的值即可

在这里插入图片描述

//改变元素
bool DoubleLinkList::change(int index, int val)
{Node* temp = get(index);if (temp) {temp -> value = val;return true;}return false;
}

查找元素

1.新建一个节点temp指向头结点head
2.不断向后移动temp并判断temp是否威空
3.最终返回索引

//查找元素
int DoubleLinkList::search(int val)
{int index = 0;Node* temp = head;while (temp->value != val) {index++;temp = temp->next;if (temp == nullptr) {cout << "未找到!" << endl;return -1;}}cout << "找到了!元素索引为:";return index;
}

测试:新建一个main文件进行测试

#include<iostream>
#include"Node.h"
#include"DoubleLinkList.h"using namespace std;void test01() {DoubleLinkList* myList = new DoubleLinkList(1);myList->append(3);myList->append(5);myList->append(7);myList->append(9);myList->PrintDoubleLinkList();myList->getLength();
}void test02() {DoubleLinkList* myList1 = new DoubleLinkList(1);myList1->append(3);myList1->append(5);myList1->append(7);myList1->append(9);//myList1->insert(5, 4);//myList1->removeLast();//myList1->remove(2);//cout<<myList1->get(4)->value<<endl;//myList1->change(2, 4);cout<<myList1->search(5)<<endl;myList1->PrintDoubleLinkList();myList1->getLength();
}int main() {//test01();test02();
}

测试结果如下:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GPT编程:运行第一个聊天程序

环境搭建 很多机器学习框架和类库都是使用Python编写的&#xff0c;OpenAI提供的很多例子也是Python编写的&#xff0c;所以为了方便学习&#xff0c;我们这个教程也使用Python。 Python环境搭建 Python环境搭建有很多种方法&#xff0c;我们这里需要使用 Python 3.10 的环境…

环境配置注解 @PostConstruct作用以及在springboot框架中的加载时间

作用 PostConstruct 是 Java EE 5 引入的一个注解&#xff0c;用于 Spring 框架中。它标记在方法上&#xff0c;以表示该方法应该在对象的依赖注入完成后&#xff0c;并且在类的任何业务方法被调用之前执行。这个注解的主要用途是进行一些初始化工作。需要注意的是&#xff1a;…

1127: 矩阵乘积

题目描述 计算两个矩阵A和B的乘积。 输入 第一行三个正整数m、p和n&#xff0c;0<m,n,p<10&#xff0c;表示矩阵A是m行p列&#xff0c;矩阵B是p行n列&#xff1b; 接下来的m行是矩阵A的内容&#xff0c;每行p个整数&#xff0c;用空格隔开&#xff1b; 最后的p行是矩…

使用docker搭建LNMP架构

目录 环境准备 下载安装包 服务器环境 任务分析 nginx部分 建立工作目录 编写 Dockerfile 脚本 准备 nginx.conf 配置文件 生成镜像 创建自定义网络 启动镜像容器 验证nginx MySQL部分 建立工作目录 编写 Dockerfile 准备 my.cnf 配置文件 生成镜像 启动镜像…

AWS云用户创建

问题 需要给工友创建AWS云的用户&#xff0c;这里假设使用分配给自己AWS开发者IAM账号&#xff0c;给别人创建aws IAM账号。 登录系统 打开页面&#xff1a;https://xxx.signin.aws.amazon.com/console&#xff0c;使用分配的开发者账号登录。如下图&#xff1a; 创建用户…

嵌入式(六)模数转换ADC | ADC 工作模式 寄存器 轮询和中断方式

文章目录 1 CC2530的ADC模块2 ADC工作模式3 ADC相关寄存器3.1数据寄存器3.2 控制寄存器 4 ADC初始化配置5 ADC使用方式5.1 轮询方式5.2 中断方式 模拟/数字转换 (Analog to Digital Converter&#xff0c;简称ADC) 是将输入的模拟信号转换为数字信号。 各种被测控的物理量&…

压缩编码之离散余弦变换(DCT)之不同块大小对图像质量和压缩效果的影响的python实现

原理 离散余弦变换&#xff08;DCT&#xff09;是一种在图像压缩中广泛使用的技术&#xff0c;特别是在JPEG图像格式中。 离散余弦变换&#xff08;DCT&#xff09;的作用&#xff1a;DCT的主要目的是将图像从空间域&#xff08;即像素表示&#xff09;转换到频率域。在频率域…

树莓派4B-Python-使用PCA9685控制舵机云台+跟随人脸转动

系列文章 树莓派4B-Python-控制舵机树莓派-Pico控制舵机树莓派4B-Python-使用PCA9685控制舵机云台跟随人脸转动&#xff08;本文章&#xff09; 目录 系列文章前言一、SG90s舵机是什么&#xff1f;二、PCA9685与舵机信号线的接线图三、控制SG90s云台&#xff08;也可用来测试舵…

Marin说PCB之传输线损耗---趋肤效应和导体损耗01

大家在做RF上的PCB走线或者是车载相机的上走线的时候经常会听那些硬件工程师们说你这个走线一定要保证50欧姆的阻抗匹配啊&#xff0c;还有就是记得加粗走做隔层参考。 有的公司的EE硬件同事会很贴心的把RF走线的注意事项给你备注在原理图上或者是layoutguide上&#xff0c;遇到…

Vue-路由-声明式导航

1. 导航链接 vue-router 提供了一个全局组件 router-link (取代 a 标签) 能跳转&#xff0c;配置 to 属性指定路径(必须) 。本质还是 a 标签 &#xff0c;to 无需 #能高亮&#xff0c;默认就会提供高亮类名&#xff0c;可以直接设置高亮样式 如&#xff1a; <div class&…

UML-顺序图

提示&#xff1a;用例图从参与者的角度出发&#xff0c;描述了系统的需求&#xff08;用例图&#xff09;&#xff1b;静态图定义系统中的类和对象间的静态关系&#xff08;类图、对象图和包图&#xff09;&#xff1b;状态机模型描述系统元素的行为和状态变化流程&#xff08;…

redis数据结构源码分析——跳表zset

文章目录 跳表的基本思想特点节点与结构跳跃表节点zskiplistNode属性 跳跃表链表属性 跳表的设计思想和优势API解析zslCreate&#xff08;创建跳跃表&#xff09;zslCreateNode&#xff08;创建节点&#xff09;zslGetRank&#xff08;查找排位&#xff09;zslDelete&#xff0…

css3 2D与3D转换

css3 2D与3D转换 前言2D变形旋转变形 rotate()transform-origin属性 缩放变形 scale()斜切变形 skew()位移变形 translate() 3D变形3D旋转 rotateX() | rotateY()perspective属性 空间移动 制作一个正方体结语 前言 网页设计不再局限于平面&#xff0c;而是充满了立体感和动态…

人工智能主流技术详解

人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;是当今科技领域发展最迅速、最令人振奋的分支之一。本文将带您深入了解人工智能的主流技术&#xff0c;探索AI如何影响我们的生活、工作以及未来的发展。 一、什么是人工智能&#xff1f; 人工智能&…

烟火检测AI边缘计算智能分析网关V4在安防项目中的应用及特点

一、行业背景 随着社会和经济的发展&#xff0c;公共安全和私人安全的需求都在不断增长。人们需要更高效、更准确的安防手段来保障生命财产安全&#xff0c;而人工智能技术正好可以提供这种可能性&#xff0c;通过智能监控、人脸识别、行为分析等手段&#xff0c;大大提高了安防…

非线性方程求根迭代法(C++)

文章目录 问题描述算法描述不动点迭代法一维情形多维情形 牛顿迭代法单根情形重根情形 割线法抛物线法逆二次插值法 算法实现准备工作一般迭代法割线法抛物线法逆二次插值法 实例分析例1例2 迭代法是一种求解非线性方程根的方法, 它通过构造一个迭代过程, 将一个非线性方程转化…

ssm基于web办事大厅政务预约系统+vue论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本办事大厅政务预约系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据…

【MySQL】聚合函数

文章目录 聚合函数是什么&#xff1f;一、AVG和SUM函数二、MIN和MAX函数三、COUNT函数四、GROUP BY1. 基本使用2. 使用多个列分组3. GROUP BY中使用WITH ROLLUP 五、HAVING1. 基本使用2. HAVING 与 WHERE 的区别 六、SELECT的执行过程1. 查询结构2. SELECT执行顺序 综合练习 聚…

关于浏览器下载的时候出现失败,网络错误

我试过所有浏览器&#xff0c;谷歌&#xff0c;firefox,qq浏览器&#xff0c;还是edge都不好使&#xff0c; 1.看网上说是http debugger的问题&#xff0c;但是我没有找到这个服务项 2.也有说可以通过修改或设置下载路径解决 -------- 我通过下载一个叫xdm的软件&#xff…

web前端算法简介之字典与哈希表

回顾 栈、队列 &#xff1a; 进、出 栈&#xff08;Stack&#xff09;&#xff1a; 栈的操作主要包括&#xff1a; 队列&#xff08;Queue&#xff09;&#xff1a; 队列的操作主要包括&#xff1a; 链表、数组 &#xff1a; 多个元素存储组成的 简述链表&#xff1a;数组&…