关于在递归中删除链表结点不会导致链表断链的理解
题目来自王道书:设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点。
这道题在开始看的时候是觉得很简单的,判断是否等于x,然后在L->next进行递归就是了,但是当我看到答案的时候就很懵了(答案如下):
void Del_x_3(Linklist &L,ElemType x)
{LNode *p;if(L==NULL)return;if(L->data==x){p=L;L=L->next;free(p);Del_x_3(L,x);}elseDel_x_3(L->next,x);
}
在王道书的答案中,在if(L->data==x)的程序段里面,没有寻找前驱结点,来改变next域,直接使用了L=L->next,在代码最后,也为我们强调了这段程序不会断链。
那首先我们需要了解,什么是断链:在这个问题中,也就是next没有指向它应该指向的地方。但在王道书上的代码,没有找前驱结点改变其next域,这就会造成断链了呀,为什么没有?这就涉及到了void Del_x_3(Linklist &L,ElemType x)在调用中使用了“引用类型”(Linklist &L)。
什么是“引用类型”,简单来说,就是给你起了个外号,你叫“李**”,别人叫你“小李同学”,这时候“小李同学”和“李**”都是指你,“小李同学”就相当于你的“引用类型”,用程序表示就是ElemType &小李同学=李**,把这个放入实际的代码例子中就相当于int &a=b,这个时候a和b就会指向同一片区域,a和b是这个片区域的不同名字而已。
同时在使用引用类型的时候需要注意以下三个规则:
(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。
(2)不能有NULL 引用,引用必须与合法的存储单元关联(指针则可以是NULL)。
(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。
//如果想要更加深入的了解引用还有引用和指针的关系可以参考这两篇文章引用和指针的区别 引用类型
讲完引用类型,接下来将为什么在递归中可以使直接删除结点不会导致链表断链。在void Del_x_3(Linklist &L,ElemType x)在调用中使用“引用类型”(Linklist &L)着使得在调用中后一个L与前一个L->next是相同的。我们假设链表元素为{1,2,2,5,6,5,2},我们在其中删除值为2 的元素,在L指向1号元素时,1!=2,因此执行Del_x_3(L->next,x),此时我们将第二轮调用的L称为L1,L1=L->next,同时L1指向了2号元素2= =2,因此需要删除,在执行L=L->next时,相当于L1=L1->next,相当于L->next=L->next->next,这下是不是和我们所熟知的式子一样了。
如图一样,L的next域(即我红色那一部分)和L1都指向了后继结点,同时,L1和L->next是共享一个数据块的,这两是同一个数据块的不同名字,所以L=L->next在我看来还有另外一个理解,就是L所代表的数据块被L->next所覆盖,而L所代表的数据块正式前驱结点的next域,即L的前驱结点next域也同时被修改了,这样便没有造成断链。之后的也是一样的,可以自己推一下。同时需要注意,在每一次递归后其实与当前L相关的只有本身和前驱结点的next域,与再之前结点并没有什么关系。
关于在递归中删除链表结点不会导致链表断链的理解相关推荐
- 链表:递归中删除结点不发生断链
这是使用递归(使用引用)进行删除节点的内存变化 void Del_x(LinkList &L, int x) {//引用if (L == NULL) {//空结点return;}LNode * ...
- 链表中删除选定结点的优雅操作!
一般我们在进行单向链表链表的结点删除操作时,都是通过相应的结构体指针进行链表的遍历,然后找 到需要删除的节点,为了完成删除操作,我们需要在寻找该节点时,不断地记录下这个节点前面的节点 (prev),来 ...
- 递归算法删除某一链表指定节点为什么不会发生断链?(解析原因)
代码段 作者:LeetCode-Solution 链接:https://leetcode-cn.com/problems/remove-linked-list-elements/solution/yi ...
- l2-004 这是二叉搜索树吗?_LeetCode 例题精讲 | 11 二叉树转化为链表:二叉树遍历中的相邻结点...
本期例题: LeetCode 98. Validate Binary Search Tree 验证二叉搜索树(Medium) LeetCode 426. Convert Binary Tree to ...
- 程序员面试题精选100题(33)-在O(1)时间删除链表结点[数据结构]
题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点.链表结点的定义如下: struct ListNode {int m_nKey;ListNode* m_pNext; }; 函数的声明如下 ...
- [剑指offer]面试题13:在O(1)时间删除链表结点
面试题13:在O(1)时间删除链表结点 题目:给定单向链表的头指针和一个结点指针,定义一个函数在 O(1)时间删除该结点.链表结点与函数的定义如下: struct ListNode {int valu ...
- 建信01. 间隔删除链表结点
建信01. 间隔删除链表结点 给你一个链表的头结点 head,每隔一个结点删除另一个结点(要求保留头结点). 请返回最终链表的头结点. 示例 1: 输入:head = [1,2,3,4] 输出: [1 ...
- 遍历Collection,避免在循环中删除对象时避免ConcurrentModificationException
我们都知道,由于ConcurrentModificationException您无法执行以下操作: for (Object i : l) {if (condition(i)) {l.remove(i) ...
- java单链表_(java实现)单链表
什么是单链表 在了解单链表之前,你知道什么是链表吗?如果你不知道什么是链表,可以看看我的这篇博客 单链表是链表的其中一种基本结构.一个最简单的结点结构如图所示,它是构成单链表的基本结点结构.在结点中数 ...
最新文章
- python位运算符
- 解决win7 64位操作系统下安装PL/SQL后连接报错问题: make sure you have the 32 bits oracle client installed
- mysql中selectform_带有select标签的form表单,怎么提交到数据库啊 ?具体情况如下...
- Spring--总体架构
- java查看jvm对象个数_jmap-查看 jvm 内存对象信息
- 4.从Paxos到Zookeeper分布式一致性原理与实践--- Zookeeper 与 Paxos
- 《私募证券投资基金业绩报酬指引(征求意见稿)》
- 中国智能硬件调研报告
- 资本市场律师David Cameron作为合伙人加入德汇律师事务所香港办事处
- 北京联通dns服务器位置,联通DNS服务器地址怎么设置
- 桌面图标的背景颜色怎么改成透明?
- python标准库calendar判断年份是闰年和平年
- [cesium] | 城市警情模拟
- 计算机U盘那种好,u盘什么主控好,u盘主控比较
- 电脑手机生产力提升操作
- GD32F450,CAN1收发数据总结
- 方正排版只支持rtf格式的文件在线打开的解决方案
- HAProxy- 日志管理
- 根据详细地址获取经纬度
- 太强了,Python还可以计算农历