基于面向对象,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.mzph.cn/news/622576.shtml

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

相关文章

如何开启文件共享及其他设备如何获取

1.场景分析 日常生活中&#xff0c;常常会遇到多台电脑共同办公文件却不能共享的问题&#xff0c;频繁的用移动硬盘、U盘等拷贝很是繁琐&#xff0c;鉴于此&#xff0c;可以在同一内网环境下设置共享文件夹&#xff0c;减少不必要的文件拷贝工作&#xff0c;提升工作效率。废话…

希尔排序和计数排序

&#x1f4d1;前言 本文主要是【排序】——希尔排序、计数排序的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一句…

Jmeter 压测接口返回大量数据时吞吐量上不去问题记录

1. 背景介绍 近期需要对外部提供一个批量查询接口&#xff0c;接口逻辑并不复杂&#xff0c;只是返回的数据有点多。分页查询&#xff0c;最大查询100个单子&#xff0c;分页单页最大值没有限制&#xff0c;那么&#xff0c;极端情况下&#xff0c;就是一次查询100个单…

【PyTorch简介】3.Loading and normalizing datasets 加载和规范化数据集

Loading and normalizing datasets 加载和规范化数据集 文章目录 Loading and normalizing datasets 加载和规范化数据集Datasets & DataLoaders 数据集和数据加载器Loading a Dataset 加载数据集Iterating and Visualizing the Dataset 迭代和可视化数据集Creating a Cust…

【Docker篇】从0到1搭建自己的镜像仓库并且推送镜像到自己的仓库中

文章目录 &#x1f50e;docker私有仓库&#x1f354;具体步骤 &#x1f50e;docker私有仓库 Docker私有仓库的存在为用户提供了更高的灵活性、控制和安全性。与使用公共镜像仓库相比&#xff0c;私有仓库使用户能够完全掌握自己的镜像生命周期。 首先&#xff0c;私有仓库允许…

力扣-盛最多水的容器

11.盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜…

C //练习 4-10 另一种方法是通过getline函数读入整个输入行,这种情况下可以不使用getch与ungetch函数。请运用这一方法修改计算器程序。

C程序设计语言 &#xff08;第二版&#xff09; 练习 4-10 练习 4-10 另一种方法是通过getline函数读入整个输入行&#xff0c;这种情况下可以不使用getch与ungetch函数。请运用这一方法修改计算器程序。 注意&#xff1a;代码在win32控制台运行&#xff0c;在不同的IDE环境下…

C语言程序设计——程序流程控制方法(二)

循环结构 while语句 while(表达式){代码块; }do{代码块; }while(表达式)while语句分为do-while和while两种&#xff0c;区别在于循环之前是不是先执行一次循环的内容&#xff0c;可以类似于i和i的关系&#xff0c;本质上来讲是相同的。当表达式为真时&#xff0c;则会执行一次…

【Java 干货教程】Java方法引用详解

导言 Java方法引用是Java 8引入的一项重要特性&#xff0c;它提供了一种简洁、可读性高的方式来直接引用已经存在的方法。方法引用使得代码更加简洁、易懂&#xff0c;同时提高了代码的可维护性和重用性。本文将详细介绍Java方法引用的概念、语法和使用方法&#xff0c;并提供…

超详细的 pytest 钩子函数 之初始钩子和引导钩子来啦

前几篇文章介绍了 pytest 点的基本使用&#xff0c;学完前面几篇的内容基本上就可以满足工作中编写用例和进行自动化测试的需求。从这篇文章开始会陆续给大家介绍 pytest 中的钩子函数&#xff0c;插件开发等等。 仔细去看过 pytest 文档的小伙伴&#xff0c;应该都有发现 pyte…

【数据结构 | 希尔排序法】

希尔排序法 思路ShellSort 思路 希尔排序法又称缩小增量法。希尔排序法的基本思想是&#xff1a;先选定一个整数&#xff0c;把待排序文件中所有记录分成个组&#xff0c;所有距离为的记录分在同一组内&#xff0c;并对每一组内的记录进行排序。然后&#xff0c;取&#xff0c…

关于Golang闭包

关于Golang闭包 1、能不用闭包的地方就不要用闭包&#xff0c;没必要为了炫技&#xff0c;写一段增加团队小伙伴负担的代码 2、for 循环代码&#xff0c;统一在内部用临时变量再存一下 for _, val : range values {val : val }在线代码演示&#xff1a;https://go.dev/play/p…

docker 支持 gpu

需求&#xff1a; 原先在宿主机里运行的服务需要迁移到docker 里 进程&#xff1a; docker 支持 gpu 需要装toolkit &#xff0c;但是正常情况下没有对应的源&#xff0c;所以先引入源文件 distribution$(. /etc/os-release;echo $ID$VERSION_ID) \ && curl -fsSL …

ospf-gre隧道小练习

全网可达,R5路由表没有其他路由器的路由条目 注:每个路由器都添加了自己的环回,如R1就是1.1.1.1 R1可以分别ping通与R2,R3,R4之间的隧道 R1路由表上有所有路由器环回的路由条目 R5路由表上没有其他路由器的路由条目 实现代码: 首先将各个接口IP配好 边上3个路由器:[R6][R7][R…

ES API 批量操作 Bulk API

bulk 是 elasticsearch 提供的一种批量增删改的操作API。 bulk 对 JSON串 有着严格的要求。每个JSON串 不能换行 &#xff0c;只能放在同一行&#xff0c;同时&#xff0c; 相邻的JSON串之间必须要有换行 &#xff08;Linux下是\n&#xff1b;Window下是\r\n&#xff09;。bul…

【谭浩强C程序设计 学习辅导第3章】最简单的C程序设计——顺序程序设计(含详细源码)

文章目录 一、 顺序程序设计题的解题思路及注意事项解题思路注意事项 二、源码讲解第3章源码文件构成&#xff1a;main.c 文件内容说明chap3.c源码实现chap3.h声明头文件测试结果展示源码链接 说明&#xff1a;本学习辅导题适用于谭浩强教辅第四版。 一、 顺序程序设计题的解题…

学习记录————

1月 1月10号 习惯这件事很重要&#xff0c;一个长期坚守的习惯不一定是最好的&#xff0c;但是是能一直坚守下去的。所以习惯不能变来变去 长期坚守的习惯是什么&#xff1f;①10点 && (视频后 || 聊完天后)两个小时学习。②上床不玩手机。③周末&#xff1a;10-12点…

Programming Abstractions in C阅读笔记:p246-p247

《Programming Abstractions in C》学习第68天&#xff0c;p246-p247总结&#xff0c;总计2页。 一、技术总结 本章通过“the game of nim(尼姆游戏)”&#xff0c;这类以现实生活中事物作为例子进行讲解的情况&#xff0c;往往对学习者要求比较高&#xff0c;需要学习者具备…

<软考高项备考>《论文专题 - 65 质量管理(4) 》

4 过程3-管理质量 4.1 问题 4W1H过程做什么为了评估绩效&#xff0c;确保项目输出完整、正确且满足客户期望&#xff0c;而监督和记录质量管理活动执行结果的过程作用&#xff1a;①核实项目可交付成果和工作已经达到主要干系人的质量要求&#xff0c;可供最终验收;②确定项目…

C# 静态代码织入AOP组件之肉夹馍

写在前面 关于肉夹馍组件的官方介绍说明&#xff1a; Rougamo是一个静态代码织入的AOP组件&#xff0c;同为AOP组件较为常用的有Castle、Autofac、AspectCore等&#xff0c;与这些组件不同的是&#xff0c;这些组件基本都是通过动态代理IoC的方式实现AOP&#xff0c;是运行时…