数据结构 链表2

目录

前言:

一,反转一个链表(迭代)

 二,打印一个链表(递归)

三,反转一个链表(递归)

四,双向链表

总结


前言:

我们根据 [文章  链表1] 可以知道链表相比较于数组的优缺点和计算机是如何管理内存的,然后介绍了链表的实现,头插法,任意节点插入,任意节点删除,接下来我们就来学习反转链表与打印链表的迭代和递归操作


 

一,反转一个链表(迭代)

反转一个链表并不是移动位置,而是改变输出方向,就好比如数组一样,我们打印一个反转的数组,就是for循环反着循环就好了,取决于下角标,而不是数据的位置,这里也是同理 

#include<iostream>
#include<new>
using namespace std;struct Node {int data;Node* Next;
};Node* head;void reverse(){Node* current, * prev, * next;current = head;  prev = NULL;while (current != NULL) {next = current->Next;current->Next = prev;  //这里可以设置第一个节点为NULLprev = current;current = next;}head = prev;
}void print() {Node* temp = head;while(temp!=NULL) {cout << temp->data << "  ";temp = temp->Next;}
}int main() {head = NULL;Node* temp1 = new Node;temp1->data = 1;temp1->Next = NULL;Node* temp2 = new Node;temp2->data = 2;temp2->Next = NULL;Node* temp3 = new Node;temp3->data = 3;temp3->Next = NULL;Node* temp4 = new Node;temp4->data = 4;temp4->Next = NULL;temp1->Next = temp2;  temp2->Next = temp3;  temp3->Next = temp4;head = temp1;reverse();print();
}

这是反转一个链表的操作,然后我们来详细的看一下这个反转链表的函数

void reverse(){Node* current, * prev, * next;current = head;  prev = NULL;while (current != NULL) {next = current->Next;current->Next = prev;  //这里可以设置第一个节点为NULLprev = current;current = next;}head = prev;
}

这里就是反转链表的函数,我们反转链表主要就是利用改变后面的指向,使得输出方向发生变化,因为head永远都是这个链表的第一个节点的位置

这里设置了三个指针

prev:    先前的      这个是用来当current为空的时候,好用prev给head提供最好一个节点的位置,还有一个就是让current指向前一个

current:现在的      这个是用来表示现在这个节点的,利用current来来指向前一个

next:    下一个的   这个是用来为current提供下一个位置的

 二,打印一个链表(递归)

 这里就不讲解递归的思想了,可以去看我的文章函数的递归

我们根据这个思想来编写这个递归思想书写这个代码

#include<iostream>
#include<new>
using namespace std;struct Node {int data;Node* Next;
};Node* head;void reverse(){Node* current, * prev, * next;current = head;  prev = NULL;while (current != NULL) {next = current->Next;current->Next = prev;  //这里可以设置第一个节点为NULLprev = current;current = next;}head = prev;
}void print1(Node* p) {if (p == NULL) {return;}cout << p->data << " ";print1(p -> Next);cout << p->data << " ";
}int main() {head = NULL;Node* temp1 = new Node;temp1->data = 1;temp1->Next = NULL;Node* temp2 = new Node;temp2->data = 2;temp2->Next = NULL;Node* temp3 = new Node;temp3->data = 3;temp3->Next = NULL;Node* temp4 = new Node;temp4->data = 4;temp4->Next = NULL;temp1->Next = temp2;  temp2->Next = temp3;  temp3->Next = temp4;head = temp1;reverse();print1(head);
}

这个里面有利用递归来书写的打印链表

if (p == NULL) {return;
}

这个为递归的基准条件,什么时候跳出递归进行反转

cout << p->data << " ";
print1(p -> Next);
cout << p->data << " ";

这个是递归的过程,上面的为正序打印,下面为逆序打印,至于为什么这样,看我的文章函数的递归

三,反转一个链表(递归)

#include<iostream>
#include<new>
using namespace std;struct Node {int data;Node* Next;
};Node* head;void reverse1(Node*p){if (p->Next == NULL) {head = p;return;}reverse1(p->Next);Node* q = p->Next;q->Next = p;p->Next = NULL;
}void print1(Node* p) {if (p == NULL) {return;}cout << p->data << " ";print1(p -> Next);
}int main() {head = NULL;Node* temp1 = new Node;temp1->data = 1;temp1->Next = NULL;Node* temp2 = new Node;temp2->data = 2;temp2->Next = NULL;Node* temp3 = new Node;temp3->data = 3;temp3->Next = NULL;Node* temp4 = new Node;temp4->data = 4;temp4->Next = NULL;temp1->Next = temp2;  temp2->Next = temp3;  temp3->Next = temp4;head = temp1;reverse1(head);print1(head);
}

我们来看这个递归反转链表的代码

void reverse1(Node*p){if (p->Next == NULL) {head = p;return;}reverse1(p->Next);Node* q = p->Next;q->Next = p;p->Next = NULL;
}

这个相较于迭代,代码量少了很多

if语句是用来设置基准条件的,着p是为了寻找最后一个节点赋值给head,另外一个就是挖掘深度,提供可以改变指向的一个环境,后面就是递归完之后,我们知道这个如果是打印数字的话就是反着来的,所以我们就知道这个已经是到最后一个节点了,然后我们只需要改变指向

  1. 递归调用过程

    • 初始调用:reverse1(head),即 reverse1(A)

    • 递归调用:reverse1(B)

    • 递归调用:reverse1(C)

    • 递归调用:reverse1(D)

    • DNextNULL 时,设置 head = D,并返回。

 我们可以知道在D的时候,Next已经为空,则这个时候就开始return了,然后我们就进入C,我们以C为例子来讲解

这个就是过程,改变下一个,本个为空

四,双向链表

struct Node {int data;Node* next;Node* prev;
};

双向链表是由两个地址域的

优点:如果我们由指向任意节点的指针,那么我们是方便反向查询的(仅需一个指针)

缺点:代码量增加,占用内存 

 双向链表的实现跟单向链表很像,只是多了一个地址域而已,这里就不过多解释了,对于堆的数据,我们链表一般都是在堆的,在堆里面查找数据一般都是利用指针


总结

我们目前基本学习完了链表的全部知识

-----增删改查

-----打印链表(迭代,递归)

-----反转链表(迭代,递归)

增删改查:这个就是要注意指向问题,比如增加到中间的位置的时候,是需要找到前面那个节点进程处理的

递归        :需要注意的就是基准条件和过程,释放到入口的上面还是下面

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

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

相关文章

考研408笔记之数据结构(五)——图

数据结构&#xff08;五&#xff09;——图 1. 图的基本概念 1.1 图的定义 1.2 有向图和无向图 在有向图中&#xff0c;使用圆括号表示一条边&#xff0c;圆括号里元素位置互换没有影响。 在无向图中&#xff0c;使用尖括号表示一条边&#xff0c;尖括号里元素位置互换则表示…

游戏设备升级怎么选?RTX4070独显,ToDesk云电脑更具性价比

过新年、添喜气&#xff01;正逢节期来临不知道各位是否都跟小编一样在考虑购置生活中的各样所需呐&#xff1f; 25年可谓是3A游戏大作之年&#xff0c;例如《GTA6》《文明7》《死亡搁浅2》《刺客信条&#xff1a;影》下半年落地的《塞尔达传说&#xff1a;新篇章》《生化危机9…

C语言初阶牛客网刷题——HJ73 计算日期到天数转换【难度:简单】

1. 题目描述——HJ73 计算日期到天数转换 牛客网OJ题链接 描述 每一年中都有 12 个月份。其中&#xff0c;1,3,5,7,8,10,12 月每个月有 31 天&#xff1b; 4,6,9,11 月每个月有 30 天&#xff1b;而对于 2 月&#xff0c;闰年时有29 天&#xff0c;平年时有 28 天。 现在&am…

【深度学习基础】多层感知机 | 权重衰减

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…

实现酷炫粒子背景效果

使用 particles.vue3 实现酷炫粒子背景效果 在这篇博客中&#xff0c;我们将介绍如何使用 particles.vue3 实现动态粒子背景&#xff0c;并详细讲解其配置参数和常见问题的解决方法。通过本文&#xff0c;你可以轻松在项目中应用并自定义粒子效果。 什么是 particles.vue3&am…

ubuntu16.04 VSCode下cmake+clang+lldb调试c++

VSCode下cmakeclanglldb调试c Ubuntu16.04 安装OpenCV4.5.4 文章目录 VSCode下cmakeclanglldb调试c1.安装clangclangdcmake2、打开VSCode&#xff0c;安装扩展插件3、编译4、Debug4.1 创建launch.json。4.2 配置setting.json 5. vscode安装配置clang-format插件5.1 Linux系统安…

在vue3中使用datav完整引入时卡在加载页面的解决方法

文件修改 文件&#xff1a;node_modules/dataview\datav-vue3/package.json // "module": "./es/index.js","module": "./es/index.mjs", // 修改后使用完整引入&#xff0c;需要为datav配置文件添加相应方法 文件&#xff1a;node…

AI agent 在 6G 网络应用,无人机群控场景

AI agent 在 6G 网络应用,无人机群控场景 随着 6G 时代的临近,融合人工智能成为关键趋势。借鉴 IT 行业 AI Agent 应用范式,提出 6G AI Agent 技术框架,包含多模型融合、定制化 Agent 和插件式环境交互理念,构建了涵盖四层结构的框架。通过各层协同实现自主环境感知等能力…

跨境电商SEO起步:关键词研究方法

SEO的重要性和必要性不言而喻&#xff0c;而在SEO的各大流程中&#xff0c;关键词研究同样重要&#xff0c;因为它在网站内容优化、产品标题和描述优化等方面都发挥重要作用。 一、从消费者视角出发 SEO是为了增加让消费者看到自己产品的可能性&#xff0c;因此要从消费者搜索…

开发环境搭建-1:配置 WSL (类 centos 的 oracle linux 官方镜像)

一些 Linux 基本概念 个人理解&#xff0c;并且为了便于理解&#xff0c;可能会存在一些问题&#xff0c;如果有根本上的错误希望大家及时指出 发行版 WSL 的系统是基于特定发行版的特定版本的 Linux 发行版 有固定组织维护的、开箱就能用的 Linux 发行版由固定的团队、社区…

【三维分割】Gaga:通过3D感知的 Memory Bank 分组任意高斯

文章目录 摘要一、引言二、主要方法2.1 3D-aware Memory Bank2.2 三维分割的渲染与下游应用 三、实验消融实验应用: Scene Manipulation 地址&#xff1a;https://www.gaga.gallery 标题&#xff1a;Gaga: Group Any Gaussians via 3D-aware Memory Bank 来源&#xff1a;加利福…

UE5 开启“Python Remote Execution“

demo 代码 remote_execution.py 远程调用UE5 python代码-CSDN博客 在启用 Unreal Engine 5&#xff08;UE5&#xff09;的“Python 远程执行”功能后&#xff0c;UE5 会启动一个 UDP 组播套接字服务&#xff0c;以监听来自外部应用程序的 Python 命令。 具体行为如下&#xf…

TangoFlux 本地部署实用教程:开启无限音频创意脑洞

一、介绍 TangoFlux是通过流匹配和 Clap-Ranked 首选项优化&#xff0c;实现超快速、忠实的文本到音频生成的模型。 本模型由 Stability AI 提供支持&#x1f680; TangoFlux 可以在单个 A40 GPU 上在 ~3 秒内生成长达 34.1kHz 的立体声音频。 二、部署 安装方式非常简单 1…

Python数据类型间的转换及eval函数

1.数据类型间的转换 x 10 y 3 z x / y # 除法运算&#xff0c;将运算的结果赋值给z print(z,type(z)) # 隐式转换&#xff0c;通过运算隐式地传了结果的类型# float类型转换为int类型&#xff0c;只保留整数部分&#xff0c;不会进行四舍五入 print(int(3.1542)) print(i…

influxdb+grafana+jmeter

influxdb influxd先启动 启动完成后执行 influxdb的端口号 grafana的启动 通过grafana-server.exe启动grafana 启动后打开 http://localhost:8087/

GeekHour

Linux Linux的是类Unix系统&#xff0c;作者是Linus&#xff0c;也是git的作者。符合GPL&#xff08;General Public License&#xff09;就可以Linux的使用、修改、再发布。 Linux四部分&#xff1a; 内核&#xff1a;驱动、内存管理、进程管理、文件系统、网络协议栈…。作…

【SpringCloud】黑马微服务学习笔记

目录 1. 关于微服务 ?1.1 微服务与单体架构的区别 ?1.2 SpringCloud 技术 2. 学习前准备 ?2.1 环境搭建 ?2.2 熟悉项目 3. 正式拆分 ?3.1 拆分商品功能模块 ?3.2 拆分购物车功能模块 4. 服务调用 ?4.1 介绍 ?4.2 RustTemplate?的使用 4.3 服务治理-注册中…

安装matlab2024a错误license checkout failed Error-8

问题&#xff1a; 忘记截图了&#xff0c;借用博主的图片。 记得安装过程中&#xff0c;目标网址才是你的安装地址&#xff0c;而不是前面的安装包地址。 解决方法&#xff1a; 1.将破解文件中"Crack\R2020a\bin\win64\matlab_startup_plugins\lmgrimpl"目录下的l…

gitlab使用多数据库

1. 说明 默认情况下&#xff0c;GitLab 使用一个单一的应用数据库&#xff0c;称为主数据库。为了扩展 GitLab&#xff0c;您可以将 GitLab 配置为使用多个应用数据库。 设置多个数据库后&#xff0c;GitLab 将使用第二个应用数据库用于 CI/CD 功能&#xff0c;称为 CI 数据库…

常用排序算法之插入排序

目录 前言 一、基本原理 1.算法步骤 2.动画演示 3.插入排序的实现代码 二、插入排序的时间复杂度 1. 时间复杂度 1.最优时间复杂度 2.最差时间复杂度 3.平均时间复杂度 2. 空间复杂度 三、插入排序的优缺点 1.优点 2.缺点 四、插入排序的改进与变种 五、插入排…