2-6 链表逆序及其C++实现

article/2025/9/20 17:17:17

 更多系列博文请点击:0-数据结构与算法链接目录 

2-6 链表逆序

我只介绍两种常用方法吧,非递归方法 和 递归 方法 我觉得够用就行

1、非递归方法:

第二个元素后面的元素依次插入到头结点后面,

最后再把原始第一个元素放到原始第二个元素后面,整个链表就能够反转了

这个方法对于带不带头结点的链表都适用:

 

①不带头结点

原始链表,其中第二个元素是 B

A -> B-> C -> D -> E -> F -> null 

先进入循环,不断的把B的后继元素往第一个元素后面插

A -> C -> B -> D -> E -> F -> null    #将上面 B后的C 插入到A后面

A -> D -> C -> B -> E -> F -> null    #将上面 B后的 D 插入到A后面

A -> E -> D -> C -> B -> F -> null   #将上面 B后的 E 插入到A后面

A -> F -> E -> D -> C -> -> null   #将上面 B后的 F 插入到A后面

最后将A放到B后面:

F -> E -> D -> C -> B -> A -> null


void Reverse(node **h) {if ((*h) == nullptr)return;else if ((*h)->next == nullptr)return;else {node *r=nullptr, *p1 = (*h), *p2 = (*h)->next;while (p2->next != nullptr) {//由于p2一直固定在原始的第2个元素//所以r一直都是取紧接着原始的第2个元素右侧的那个元素地址r = p2->next;p2->next = r->next;//将r插入到第1个元素后面,这里因为第1个元素的位置P1也不变,所以也很简单r->next = p1->next;p1->next = r;}//最后再来处理原始的第1个元素P1 和 原始的第2个元素P2的顺序p2->next = p1;(*h) =p1->next;p1->next = nullptr;}
}

②带头结点的链表

可以将头结点视为第一个元素,那么就是直接把 A 的后继元素不断的往head后面插:

带头结点原始链表,将头结点视为第1个元素,那么其中第2个元素是 A

Head -> A -> B -> C -> D -> E -> F -> null

先进入循环,不断的把A的后继元素往头结点后面插

Head -> B -> A -> C -> D -> E -> F -> null

Head -> C -> B -> A -> D -> E -> F -> null

Head -> D -> C -> B -> A -> E -> F -> null

Head -> E -> D -> C -> B -> A -> F -> null

Head -> F -> E -> D -> C -> B -> -> null

只不过最后不用将第一个元素放到A后面,也就是不用修改头指针

void Reverse(node *h) {if (h->next == nullptr) {cout << "这是空表!" << endl;return;}else if (h->next->next == nullptr) {cout << "只有一个元素,无需反转!" << endl;return;}else {node *p2 = h->next;//将头结点视为第1个元素,那么数据首节点就视为第2个元素node *r;/*将第二个元素后面的元素依次插入第一个元素后面*/while (p2->next != nullptr) {//由于p2一直固定在原始的第2个元素//所以r一直都是取紧接着原始的第2个元素右侧的那个元素地址r = p2->next;p2->next = r->next;//将r插入到头结点后面r->next = h->next;h->next = r;}//最后与不带头结点的单链表的区别就是,不用修改头指针了}
}

 

2、递归方法

①不带头结点

递归其实就是一直要找到最后一个结点,然后每次改一下,

这个时候其实 函数递归的时,函数用栈存储了前面每个结点的信息,所以一步一步从最后面改动到前面去,图我也就不画了,

画起来麻烦,可以参考一下这个博文的图,https://blog.csdn.net/fx677588/article/details/72357389,

node* ReverseList_Recursion(node *p) {/*结束的条件:链表为空或者链表最后一个节点*/if (p == nullptr || p->next == nullptr) {return p;}//递归调用node *NewHead = ReverseList_Recursion(p->next);//每次都把当前结点 重新设置成 当前结点的下一个结点的下一个结点p->next->next = p;//然后再把当前结点的新后继设置为空,相当于当前结点时新链表的尾结点p->next = nullptr;return NewHead;
}

要调用此函数的时候,假设已经存在单链表的头指针:list1_h;

直接:node * list_2 = ReverseList_Recursion( list1_h );

这样新的头指针list_2就是反转后的链表的头指针

 

②带头结点 

其实依然可以用上面的函数,只是,

对于带头结点的链表,直接向上面那样 把 头结点的地址作为参数传递进去 是不行的!

因为头结点其实并不是数据元素,数据域的值是随机的,这样直接操作会把头结点最后当做逆序后的尾结点,

另外①中直接返回一个新的头指针,其实就是原来的尾结点的地址,这样一来①中的函数其实是返回了一个以原始尾结点的地址为头指针的 无头结点单链表!

所以我们改一下调用的那行代码,就可以拿来对带头结点的单链表 进行逆序操作了:

list2->next = ReverseList_DG(list2->next)

上面这行代码,是把带头结点的单链表的下一个元素,也就是数据首元素的地址传入了递归函数中!(其实带头结点的单链表不看头结点就是 一个不带头结点的单链表)

然后把返回的 新的地址,又接入到 头结点的后面!

这样就可以在不改变原来头结点 地址 的情况下, 仅对数据部分进行逆序啦。

 

 

若有错误,还请不吝指出,谢谢

 更多系列博文请点击:0-数据结构与算法链接目录 

 

 

 

 

 

 


http://chatgpt.dhexx.cn/article/v4rU5g54.shtml

相关文章

c语言 数据结构 双向循环链表逆序

双链循环链表排序&#xff1a; 原链表&#xff1a; 1 2 3 4 5 6 7 8 9 10 逆序后&#xff1a;10 9 8 7 6 5 4 3 2 1 思路&#xff1a; 把最后一个节点删除&#xff0c; 插到head下面去 数据 1 不用管&#xff0c; 把后面的数据往 1 前面怼&#xff0c; 1自然就是最后一个了…

C语言实现链表的逆序的几种方式

文章目录 通过头插法实现的通过双指针实现链表的逆序通过栈来实现的通过递归来实现 通过头插法实现的 1、通过头插法&#xff08;两条链表&#xff09;来实现的。通过遍历原来的链表&#xff0c;将遍历得到的每一个节点都插入到新链表的头结点&#xff0c;然后遍历新链表&…

C语言单向链表的逆序输出

最近在学习链表&#xff0c;看到书上说可以采取每次在链表头部插入新增节点的方法&#xff0c;将链表逆序&#xff0c;也就是建立的链表节点内容与数据的输入顺序相反。我便来了兴趣&#xff0c;想着试试看&#xff0c;结果没搞懂&#xff0c;于是开始百度。看了几遍博客后终于…

样本方差与总体方差的区别

为什么80%的码农都做不了架构师&#xff1f;>>> 之前一直对于样本方差与总体方差的概念区分不清&#xff0c;对于前者不仅多了“样本”两个字&#xff0c;而且公式中除数是N-1&#xff0c;而不是N。现在写下这么写东西&#xff0c;以能彻底把他们的区别搞清楚。 总…

彻底理解样本方差为何除以n-1

设样本均值为&#xff0c;样本方差为&#xff0c;总体均值为&#xff0c;总体方差为&#xff0c;那么样本方差有如下公式&#xff1a; 很多人可能都会有疑问&#xff0c;为什么要除以n-1&#xff0c;而不是n&#xff0c;但是翻阅资料&#xff0c;发现很多都是交代到&#xff0c…

证明样本方差不是总体方差的无偏估计(1)

无偏估计是用样本统计量来估计总体参数时的一种无偏推断。估计量的数学期望等于被估计参数的真实值&#xff0c;则称此估计量为被估计参数的无偏估计&#xff0c;即具有无偏性&#xff0c;是一种用于评价估计量优良性的准则。无偏估计的意义是&#xff1a;在多次重复下&#xf…

总体方差与样本方差分母的小小区别,n还是n-1?

总体方差与样本方差分母的小小区别&#xff0c;n还是n-1&#xff1f; 引入方差概念方差计算无偏估计 样本方差公式相关参考链接 样本方差的自由度是n-1 引入 方差概念 方差是在概率论和统计方差衡量随机变量或一组数据时离散程度的度量&#xff0c;用来度量随机变量和其数学期…

样本方差的与方差

之前做模型拟合的时候需要计算样本的方差和均值,Matlab的std函数算出来就是不对经,一看才知道matlab的给定的标准差计算公式是: For a random variable vector A made up of N scalar observations, the standard deviation is defined as where μ is the mean of A: The s…

总体样本方差的无偏估计样本方差为什么除以n-1

总体样本方差的无偏估计样本方差为什么除以n-1 本文链接&#xff1a; https://blog.csdn.net/qq_16587307/article/details/81328773 我们先从最基本的一些概念入手。 如下图&#xff0c;脑子里要浮现出总体样本&#xff0c;还有一系列随机选取的样本。只要是样本&#xff0c;…

有偏样本方差、无偏样本方差

1.有偏样本方差、无偏样本方差 笔记来源&#xff1a;Why Dividing By N Underestimates the Variance 1.1 为什么样本方差总是小于总体方差&#xff1f; 由于总体量太大&#xff0c;我们要耗费大量人力物力财力才可以或者永远无法了解总体情况&#xff0c;所以我们只能用样本…

C# 及excel中【总体方差】、【样本方差】的计算公式

一、数学公式 二、C#中的数学包 using MathNet.Numerics.Statistics; 三、【总体方差】和【样本方差】的计算 using System; using System.Linq;var myList new List<float> {1,3,4,5,6,7};display("要计算的数据"); display(myList);var pv myList.Popula…

用Python计算样本方差,总体方差,比较

1.样本方差 #样本方差&#xff0c;考虑自由度def f_sigma(x):# 通过Python定义一个计算变量波动率的函数# x&#xff1a;代表变量的样本值&#xff0c;可以用列表的数据结构输入n len(x)u_mean sum(x)/n #计算变量样本值的均值z [] #生成一个空列表for t in range(n):z.…

总体方差与样本方差

今天在计算一类数据的协方差时遇到个问题。数据如下&#xff1a; x1(0,0,0)’ x2(1,0,0)’ x3(1,0,1)’ x4(1,1,0)’ 这本是一件很容易的事&#xff0c;但我手算后用Matlab的cov函数验算了一下&#xff0c;发现结果竟然不一样&#xff0c;于是按照协方差公式&#xff0c;一…

统计学---之样本方差与总体方差的区别

前段日子重新整理了一下这个问题的解答&#xff0c;跟大家分享一下&#xff0c;如果有什么错误的话希望大家能够提出来&#xff0c;我会及时改正的&#xff0c;话不多说进入正题&#xff1a; 首先&#xff0c;我们来看一下样本方差的计算公式&#xff1a; 刚开始接触这个公式的…

为什么样本方差里面要除以(n-1)而不是n?

前段日子重新整理了一下这个问题的解答&#xff0c;跟大家分享一下&#xff0c;如果有什么错误的话希望大家能够提出来&#xff0c;我会及时改正的&#xff0c;话不多说进入正题&#xff1a; 首先&#xff0c;我们来看一下样本方差的计算公式&#xff1a; 刚开始接触这个公式的…

ECS_FDS小议贝塞尔校正(Bessel‘s Correction)

在学习概率论与数理统计的相关知识时&#xff0c;大家肯定会听到”贝塞尔校正&#xff08;Bessels Correction&#xff09;“这个名词&#xff0c;这是德国天文学家&#xff0c;数学家Friedrich Bessel在进行天体测量学研究时提出的一个方法。可能大家看到一个以人名命名的概念…

样本方差与总体方差

样本方差与总体方差 一、方差&#xff08;variance)&#xff1a;衡量随机变量或一组数据时离散程度的度量。 概率论中方差用来度量随机变量和其数学期望&#xff08;即均值&#xff09;之间的偏离程度。 统计中的方差&#xff08;样本方差&am…

完整的Axios封装-单独API管理层、参数序列化、取消重复请求、Loading、状态码...

前言 Axios 相信对Vue熟悉的铁汁对它不会感到陌生了&#xff08;当然不熟悉Vue你也可以认识它&#xff09;&#xff0c;这简直就是前端近年来的一大杀器&#xff0c;自从Vue2开始之后&#xff0c;官方推荐使用axios来进行网络请求&#xff0c;后面基本大部分Vue项目都能瞧见它…

Ajax介绍和Axios基本使用

Ajax介绍 Ajax本身就是Asynchronous JavaScript And XML的缩写&#xff0c;直译为&#xff1a;异步的JavaScript和XML。 在实际应用中Ajax指的是&#xff1a;不刷新浏览器窗口&#xff0c;不做页面跳转&#xff0c;局部更新页面内容的技术。 『同步』和『异步』是一对相对的…