关于递归函数,非递归函数中引用传参的问题
首先 我们来看这个函数
typedef int Ele;
typedef struct list{Ele data;list *next;
}List,*LNode;
void dele2(LNode &l,Ele e){if(l==NULL)return;printf("Hello!!\n");printf("to %d\n",l);if(l->data==e){LNode p = l;l = l->next;//***free(p);dele2(l,e);}else dele2(l->next,e);printf("back %d\n",l);
}
这个函数就是将链表中所有为x的节点全部删除的操作
但是传参的时候传入的是一个指向链表节点指针的引用类型 也就是说在其中打***的地方
不会因为没有把前面的节点链接到后面而导致断链 相反
这里的l = l->next 是把当前节点的地址指向了后面
比如对于1 3 1这个链表 删除3操作
第一次走到1 那么递归层数加1时 调用dele2(l->next,e); 相当于(*l).next 将该指针所指向的next域的值
取出来并付给更深一层的参数 也就是引用指针&l 那么在此时在删除3时
会触发***处的操作 那么这里的操作实质上是 (*l).next = (*(*l).next).next
就相当于直接在1节点的next值修改成了 最后一个节点的地址 也就是相当于整个递归过程中对引用指针的操作其实就是对原表
操作
那么引用就是这样
在递归调用的时候 可以直接对原表操作 而且无视可能的断链情况
再来看一个函数
void delehead(LNode &p,Ele x){while(p!=NULL){ if(p->data == x){LNode q = p;p = p->next;// pre->next = p;free(q);}else {// pre = p;p = p->next; }}
}
相同的操作 就是把递归改成非递归了 相同的是引用 但是这种情况下 就会导致断链
因为当在递归中使用引用的过程时 递归结束时会把一层层加上的取值操作符再把取值操作符一层层摘掉
而这里却是让p不断指向next 指到最后变成空 因为这里没有递归函数中返回的操作
1 3 1中执行结束的时候 递归不断返回后 原指针指向的是首节点
而非递归中由于没有返回操作 会不断地让头指针所指向的值一直向后走 最后使头指针
指到最后的NULL处
所以应另外使用指针非指针引用 这样不会修改原表的地址 并且附加前后链接操作
如果为了防止首元素删除导致头指针找不到首节点 应该另外设置头结点 或者 用计数另外记录下修改后头指针
应指向的位置 所以应改为
void delehead(LNode &l,Ele x){// l指向头结点LNode p = l->next,pre = l;// p指向头节点的后继节点 pre指向头节点 // no head nodewhile(p!=NULL){ if(p->data == x){LNode q = p;p = p->next;pre->next = p;free(q);}else {pre = p;p = p->next; }}
}
这样就处理了非递归情况下对链表中删除任意位置值为x的操作 如果这里用头指针的单链表
会可能导致由于第一个节点的释放从而头指针指向了一个释放内存的地址
关于递归函数,非递归函数中引用传参的问题相关推荐
- 【php7扩展开发四】函数的参数 ,引用传参 ,返回值
函数参数解析 之前我们定义的函数没有接收任何参数,那么扩展定义的内部函数如何读取参数呢?用户自定义函数在编译时会为每个参数创建一个zend_arg_info结构,这个结构用来记录参数的名称.是否引用传 ...
- c++ 引用传参和指针传参的区别
概念 指针从本质上讲是一个变量,变量的值是另一个变量的地址,指针在逻辑上是独立的,它可以被改变的,包括指针变量的值(所指向的地址)和指针变量的值对应的内存中的数据(所指向地址中所存放的数据). 引用从 ...
- Python当中的a += a 与 a = a + a 的区别,可变类型与不可变类型的数据类型,引用传参...
a += a 与 a = a + a 的区别 可变类型a = a + a 的示例 In [58]: a = [11,22]In [59]: id(a) Out[59]: 140702917607688 ...
- 在Java中动态传参调用Python脚本
最近,又接触到一个奇葩的接口,基于老板不断催促赶时间的情况下,在重写java接口和复用已有的python脚本的两条路中选择了后者,但是其实后者并没有好很多,因为我是一个对python的认识仅限于其名称 ...
- C语言与java中函数传参比较
C语言与java中函数传参比较 首先先说结论:C语言中参数传递有值传递,地址传递,引用传递.但java中的参数传递只有值传递 1.C语言中的参数传递 1>值传递 值传递非常好理解,其实就是对函数 ...
- JS中函数传参按照值传递
ES语法中所有函数的参数都是按值传递的. 探讨函数参数按值传递问题: //1.参数被赋值为原始值 function add(num){num += 10;return num; } let count ...
- python解包裹_关于Python中包裹传参和解包裹的理解
原标题:关于Python中包裹传参和解包裹的理解 1.包裹传参 首先思考一个问题:为什么要有包裹传参?原因包括但不仅限于以下两点:①不确定参数的个数.②希望函数定义的更加松散灵活 包裹传参分两种:包裹 ...
- shell脚本中编写SQL中 以传参(${accdate})的方式 动态:求 前12个月的日期和求 前一周(7天的日期)
shell脚本中 编写SQL中 以传参(${accdate})的方式 动态 求 前12个月的日期 CAST(CAST(DATE_FORMAT(DATE_SUB(from_unixtime(unix_t ...
- php值传参,引用传参以及对象传参
传值:是把实参的值赋值给行参 ,那么对行参的修改,不会影响实参的值 传引用 :真正的以地址的方式传递参数传递以后,行参和实参都是同一个对象,只是他们名字不同而已对行参的修改将影响实参的值 说明: 传值 ...
最新文章
- mysql internal_MySQLInternal笔记
- 给网页图标字体 Font Awesome 添加动画效果
- Linux用户和用户组管理常见问题
- 服务器系统杀毒系统崩溃怎么恢复,系统崩溃是什么原因导致的
- tcp前4字节消息长度_网络基础篇之TCP
- java swing panel问题_关于 Java swing Box 的使用问题
- zabbix java api
- Hazelcast更换CEO,承诺继续造福开源社区
- WINDOWS NT/2000下如何屏蔽CTRL+ALT+DEL
- IIS启用GZip压缩
- 登录时记住密码的实现
- 智能车基于RT1064+无线串口透传模块利用MATLAB辅助调节PID参数
- 完美适配Windows 11,搜狗输入法智能输入助手体验再升级
- 支持跨平台的移动开发工具大盘点!
- 高可靠环境 FileNet 系统介绍和应用实例
- 七、vertical-align属性、透明度属性及兼容、ps常用工具、常见的图片格式、项目规范、命名参考、iconfont的使用
- 剑指Offer题目详解(CPP、JAVA)
- 计算机网络 概述重点(全)
- 51单片机控制步进电机启停,正反转速度——入门
- KMP算法之next数组详解
热门文章
- POJ 1300 Door Man(欧拉回路的判定)
- SQL Server 自定义函数 返回树结构函数
- UCenter 表结构
- 奇怪的问题,再次启动jar包会导致bean对象失效?Unknown redis exception Cannot connect, Event executor group is terminated
- vue省市区三级联动mysql,js/json,html/jsp
- android 万能倒计时,时分秒倒计时
- java接口与集合_【总结】Java常用集合接口与集合类
- mysql 错误问题_Mysql常见的几个错误问题及解决方法:
- mysql 中有没有临时表_MySQL临时表的简单用法
- dos安装深度linux,U盘用grub4dos引导Deepin v20 Beta iso安装的方法