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

news2024/11/20 10:42:13

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

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.coloradmin.cn/o/1384263.html

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

相关文章

Python-高阶函数

在Python中&#xff0c;高阶函数是指能够接收函数作为参数&#xff0c;或者能够返回函数的函数。这种特性使得函数在Python中可以被灵活地传递和使用。以下是一些关于Python高阶函数的详细解释&#xff1a; 函数作为参数&#xff1a; 高阶函数可以接收其他函数作为参数。这样的…

C语言 - 最简单,最易懂的指针、引用讲解

一、变量、地址、变量值 二、直接上代码&#xff0c;一边看上图&#xff0c;一边讲解 #include <stdio.h>struct Hello {int a;int b; };int main() {struct Hello h;h.a 10;h.b 20;struct Hello *hp;hp &h;printf("1: h的地址是%d&#xff0c;hp地址是%d \…

89.乐理基础-记号篇-省略记号-震音、音型与小节反复

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;88.乐理基础-记号篇-反复记号&#xff08;二&#xff09;D.C.、D.S.、Fine、Coda-CSDN博客 省略记号总结图&#xff1a;有些素材会把它们归纳到反复记号里&#xff0c;因为它们也涉及到 重复、反复的概念&#xff…

Open3D 两片点云的最小/最大距离(23)

Open3D 两片点云的最小/最大距离(23) 一、效果展示二、使用步骤1.代码三、cloudcompare量距小工具一、效果展示 算法与实际量测的结果保持一致,输出最近距离和对应点 二、使用步骤 1.代码 import open3d as o3d import numpy as np# 读取点云数据 cloud_2 = o3d.io.re…

查询和结果处理的Java代码

match_all查询&#xff1a; //查询所有文档 match_all查询Testvoid testMatchAll() throws IOException {// 1.准备RequestSearchRequest request new SearchRequest("hotel");// 2.准备DSLrequest.source().query(QueryBuilders.matchAllQuery());// 3.发送请求Sea…

Linux Centos7静默安装(非图形安装)Oracle RAC 11gR2(Oracle RAC 11.2.0.4)

Oracle RAC (全称Oracle Real Application Clusters &#xff09;静默安装&#xff08;非图形安装&#xff09;教程。 由于这篇文章花费了我太多时间&#xff0c;设置了仅粉丝可见&#xff0c;见谅。 环境说明&#xff1a; 虚拟机软件&#xff1a;VMware Workstation 16 Pro…

Spring Boot - Application Events 的发布顺序_ApplicationPreparedEvent

文章目录 Pre概述Code源码分析 Pre Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent 概述 Spring Boot 的广播机制是基于观察者模式实现的&#xff0c;它允许在 Spring 应用程序中发布和监听事件。这种机制的主要目的是为了实现解耦&#…

Android基于Matrix绘制PaintDrawable设置BitmapShader,以手指触点为中心显示原图像圆图,Kotlin(3)

Android基于Matrix绘制PaintDrawable设置BitmapShader&#xff0c;以手指触点为中心显示原图像圆图&#xff0c;Kotlin&#xff08;3&#xff09; 在 Android基于Matrix绘制PaintDrawable设置BitmapShader&#xff0c;以手指触点为中心显示原图像圆图&#xff0c;Kotlin&#…

网络地图服务(WMS)详解

文章目录 1.概述2.GetCapabilities3.GetMap4.GetFeatureInfo 阅读本文之前可参考前文&#xff1a;《地图服务器GeoServer的安装与配置》与《GeoServer发布地图服务&#xff08;WMS、WFS&#xff09;》。 1.概述 经过前文的介绍&#xff0c;相信我们对WMS/WFS服务已经有了一个非…

基于Token认证的登录功能实现

Session 认证和 Token 认证过滤器和拦截器 上篇文章我们讲到了过滤器和拦截器理论知识以及 SpringBoot 集成过滤器和拦截器&#xff0c;本篇文章我们使用过滤器和拦截器去实现基于 Token 认证的登录功能。 一、登录校验 Filter 实现 1.1、Filter 校验流程图 获得请求 url。判…

Express 应用生成器(脚手架)的安装与使用

1、简介 自动生成一个express搭建的项目结构 官网&#xff1a;Express 应用生成器 2&#xff0c;使用 2.1全局安装&#xff0c;使用管理员打开命令窗口 2.2、安装express # 全局安装express npm install -g express # 全局安装express脚手架 npm install -g express-gene…

BRC20通证的诞生与未来展望!如何导入bitget教程

BRC-20通证是什么&#xff1f; 嘿&#xff01;你知道BRC-20通证吗&#xff1f;这可是比特币区块链上的超级明星&#xff01;它们不依赖智能合约&#xff0c;而是把JSON代码刻在聪上&#xff0c;聪可是比特币的最小单位哦&#xff01;就像在比特币的乐高积木上盖房子&#xff0…

【量化交易故事】小明开启了量化创业之旅-01

故事开始于2023年的春天&#xff0c;小明是一位对金融市场充满热情的IT工程师。在经历了数次基于主观判断和个人情绪进行投资却收获平平后&#xff0c;他意识到传统交易方式中的人为因素难以避免&#xff0c;而这往往成为影响投资决策稳定性和准确性的关键障碍。在一次偶然的机…

bash shell基础命令

1.shell启动 shell提供了对Linux系统的交互式访问&#xff0c;通常在用户登录终端时启动。系统启动的shell程序取决于用户账户的配置。 /etc/passwd/文件包含了所有用户的基本信息配置&#xff0c; $ cat /etc/passwd root:x:0:0:root:/root:/bin/bash ...例如上述root账户信…

WorkPlus领先企业即时通信软件,提升团队沟通效率的利器

在企业工作中&#xff0c;高效沟通是推动团队协作和工作效率的关键。而企业即时通信软件成为了实现高效沟通的利器。作为一款领先的企业即时通信软件&#xff0c;WorkPlus以其卓越的性能和独特的功能&#xff0c;提升团队沟通效率&#xff0c;助力企业实现高效协作。 为什么选择…

Netty-Netty实现自己的通信框架

通信框架功能设计 功能描述 通信框架承载了业务内部各模块之间的消息交互和服务调用&#xff0c;它的主要功能如下&#xff1a; 基于 Netty 的 NIO 通信框架&#xff0c;提供高性能的异步通信能力&#xff1b; 提供消息的编解码框架&#xff0c;可以实现 POJO 的序列化和反…

QT上位机开发(usb设备访问)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 利用usb接口访问底层下位机&#xff0c;这是一种很常见的方式。目前比较简单的做法有两种&#xff0c;一种是usb转串口&#xff0c;另外一种是利用…

【期末考试】数据库综合复习宝典

目录 第一章 数据库系统概述 第二章 关系代数 第四章 关系数据库理论 第五章 数据库设计 第六章 数据库管理系统 第八章 事务管理 第一章 数据库系统概述 1.1三级模式 ①外模式&#xff1a;它为特定的应用程序或用户群体提供了一个数据视图&#xff0c;这个视图是独立于…

Qt编译OpenCV

1.CMake下载安装 官网地址&#xff1a;CMake - Upgrade Your Software Build System &#xff08;1&#xff09;下载后双击安装 &#xff08;2&#xff09;进入安装界面&#xff0c;点击【Next】 &#xff08;3&#xff09;同意协议&#xff0c;点击【Next】 &#xff08;4&a…

illustrator脚本 018 自动角线-1

这是一个自动加角线的脚本,来源于网络。 运行方式,先选择对象再执行脚本,无对话框。脚本不在好坏,你觉得对你有用最重要。 脚本中部分可修改选项: //初始化自定义标线的长度,宽度,离岸,出血等参数,可自行修改 lw=0.1*2.834646; //标线宽度 0.1 mm od=3*2.834646; //…