链表中的指针

中期答辩改在了国庆之后,终于有时间可以看看剑指offer了。在看到单向链表的部分,对指针,尤其是头指针有点疑惑。首先容易理解的是链表的节点是一个结构体,该结构体包含一个数据(一般是int型),还包含一个指向该结构体类型的指针。通过指针的指向一个个遍历,也是通过指针一次次分配内存。这使得链表不同于数组,链表中的内存不是连续的,我们想要访问一个结点只能从头结点开始。其实数组之所以能通过数组下标进行访问,也是因为事先设定了一个基准点。只不过在链表中这个基准点(头指针)很重要。现在就来好好研究一下头指针、头结点的那些事。

 

在书中提供的代码中,无论是在链表末尾插入新的结点,还是在链表中删除具有某值的结点,都有两个共同点。一是函数的第一个参数类型是指向结点数据类型的指针的指针,一是将代码分为两部分,第一部分都是通过头指针是否是空指针判断该链表是否是空链表,或者判断头结点中的数据是否和参数相等。这里提到了两个重要的概念,头指针和头结点。

struct ListNode
{int value;ListNode * Next;};void addTotail(ListNode ** head, int value){//第一个参数是头指针的指针,因为头指针在变ListNode* newlistnode = new ListNode();newlistnode->value = value;newlistnode->Next = NULL;//新建一个节点,数据等于参数,指针为空if (*head == NULL){//头指针,指向下一个节点*head = newlistnode;//空链表中插入节点,则头指针不再是空指针,第一个形参应改变}else {//链表不空时,递归直到链表尾(空指针)ListNode* pNode = *head;while (pNode->Next != NULL){pNode = pNode->Next;}pNode->Next = newlistnode;}
}

可以看到空指针相对于数组名,是链表的名字,它是指向下一个结点的指针的指针,至于为什么是双重指针,这涉及到函数中参数值的传递。因为在链表中插入我们要讨论该链表是否是空链表,进行不同的操作,而插入这个操作会使得空链表不再空,即使得原来空链表的头指针指向空指针变成了指向一个真实的结构体,我们需要在执行完一次函数后修改头指针这个形参,方便之后再次调用这个函数。

函数中值的传递方式有三种:值传递,地址传递,引用传递。

值传递,只传递了形参的值,因为在函数内部会新建值等于参数的副本(形参),函数中的操作只是对副本进行修改,不会改变实参的原始大小。实参是主函数调用函数时传递的值,形参是函数定义时使用的值。一个很形象的例子就是餐厅中有保鲜膜包好的样品菜,你指给厨师说要菜A,厨师会拿新的食材重新做一份,而不是直接把样品给你。如果真的想要样品中的菜,那么就要借助装样品的盘子了,盘子就相当于地址,这就是地址传递。Java中只有按值传递,这也是java简单的原因。

引用传递。首先搞清楚引用是怎么回事,引用是两个变量名表示同一个东西,不会分配新的内存,可以认为引用是目标变量的一个别名。通过引用修改变量势必引起原始变量发生变化。

下面说一下今天遇到的主角,指针传递。这里更特殊的是使用了双重指针。这里有一句比较容易引起混淆的话:其实一切传递的方式本质都是按值传递。简单来说,双重指针通过传递地址变量和地址指针指向的内容实现了可以通过函数对参数的地址和内容值进行修改。

先看下面一个代码,代码中第一个参数是指向int型的指针,传入a的地址。可以理解为&a是按值传递的,这样在执行函数时会有一个a的地址的拷贝,这个拷贝同样指向a,这样当我们在函数中修改拷贝中的内容,即便这个拷贝最后被释放,还是会改变a的值。

void change(int *_a,int &b){
*_a=b;
}
void main(){
int a=10,b=20;
int *p_a=&a;
change(p_a,b);
printf("%d",*p_a);
}

既然单指针作为形参已经可以实现通过函数修改实参,为什么还要使用双重函数呢?可以注意到我们刚才把a的地址当做按值传递,而函数目标是修改按值传递的地址指向的内容,但是当我们函数的目的是修改地址本身时,又回到了按值传递的老路上,这样是不能实现目的的。借鉴刚才的通过指针改变指针指向的内容,我们再加一层指针,指向变量的地址,即指针的指针,这就有了双重指针。

再说回头指针和头结点。头指针是必要的,头结点更多是为了操作统计和方便,其数据域一般无意义,可以用作监视哨或者存放链表的长度。代码中,只要头指针运用了next操作就自动创建了头结点。再从表示的意义理解一下双重指针ListNode ** pHead,它是指向结构体ListNode的指针的指针,那么*pHead表示的就是指向ListNode的一个指针。

Reference:

  1. 盘子https://blog.csdn.net/ThereIsNoCode/article/details/77996799
  2. 双重指针https://blog.csdn.net/qq_33631303/article/details/78007413
  3. https://blog.csdn.net/xmrforever/article/details/3915665
  4. https://blog.csdn.net/playboy_lei/article/details/51993513

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

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

相关文章

实现TFrecords文件的保存与读取

import os import cv2 import numpy as np import tensorflow as tf """ 将train文件夹下的cats和dog文件夹处理成train.tfrecords放在train文件夹里 """ #将图片的路径和对应的标签存储在list中返回 def deal(dir):images []temp []for root,…

工具推荐-css3渐变生成工具

今天工作用到了css3渐变,但是写起来才发现太麻烦了,而却很浪费时间,所以在这里向大家推荐一个在线的css3 渐变生成工具 地址是:http://www.colorzilla.com/gradient-editor/ 这个工具是可视化视图,用起来就和photoshop…

神经网络相关的笔试题目集合(一)

在找工作的过程中发现好多公司没有专门的、传统的图像处理岗位,所以只能参加算法类的笔试甚至AI类的笔试。在AI的笔试中几乎全是关于神经网络的问题,其实也都是很基础的一些问题,如果事先做了准备,可以从容应对。而对于我这种从传…

中美超算“你追我赶” 中国优势可圈可点

来源:新华网摘要:中美超算“你追我赶” 中国优势可圈可点新一期全球超级计算机500强榜单12日在美国达拉斯发布。与半年前的榜单相比,全球格局变化不大,美国在最快超算上…

吴恩达作业1:逻辑回归实现猫的分类

思路:输入样本X与随机初始权重W相乘,利用sigmoid激活函数输出值,对于二分类问题,用交叉熵损失函数来计算损失值,通过交叉熵损失函数利用链式法则求出W和b的偏导,梯度下降更新W和b即可,&#xff…

双摄与双目视觉

越来越多的手机开始上双摄,首先解释一下双摄的目的,双摄可以达到什么样的效果。首先双摄可以分为两类,一类是利用双摄获得图像中物体到镜头或者焦距的距离,得到景深信息就可以进行后续的3D重建、图像分割、背景虚化等;…

“脑补”的科学依据:眼前的黑不是黑,靠得是你的大脑

一个在眨眼的婴儿 | 图片来源:Leungcho Pan/Shutterstock撰文:Mindy Weisberger来源:科研圈编译:向菲菲人们常说:“别眨眼,精彩稍纵即逝。”但其实在我们眨眼的时候,精彩仍在我们眼前上演。我们…

基于Sql Server 2008的分布式数据库的实践(三)

配置PHP 1.打开PHP配置文件,找到extensionphp_mssql.dll,将前面的注释符号去掉 2.找到mssql.secure_connection,将Off改为On 3.找到com.allow_dcom true,将前面的注释符号去掉 4.下载正确版本的 ntwdblib.dll (2000.80.194.0)&am…

ORB论文研读与代码实现

首先,ORB算法来自于OpenCV Labs,相比于SIFT和SURF,ORB在使用中不必担心专利的问题。但同时ORB在保证了一定性能的条件下做到了高效。在论文《ORB: An efficient alternative to SIFT or SURF》2011中,ORB在特征点检测和描述子生成…

腾讯发布人工智能辅助翻译,致敬人工翻译

来源:腾讯AI实验室11月13日,深圳 - 腾讯AI Lab今日发布了一款AI辅助翻译产品 - “腾讯辅助翻译”(Transmart),可满足用户快速翻译的需求,用AI辅助人工翻译提高效率和质量。该产品采用业内领先的人机交互式机…

吴恩达作业2 利用两层神经网络实现不同颜色点的分类,可更改隐藏层数量

任务:将400个两种颜色的点用背景色分为两类。 前面的还是建议重点学神经网络知识,至于数据集怎么做的后面在深究,首先先看看数据集,代码如下: def load_planar_dataset():np.random.seed(1)m 400 # number of exampl…

利用tensorflow构建AlexNet模型,实现小数量级的猫狗分类(只有train)

首先看路径: data文件夹分为,model文件夹,train文件夹和文件夹,model文件夹存放模型文件,train存放cat和dog的两个文件夹图片, validation和train一样。config.py存放配置的一些参数,util.py定…

脑网络的可塑性——随时都在发生

来源:神经科技前沿神经元的突起是神经元胞体的延伸部分,由于形态结构和功能的不同,可分为树突(dendrite)和轴突(axon);树突是从胞体发出的一至多个突起,呈放射状。轴突每个神经元只有一根胞体发出轴突的细胞 质部位多呈…

KAZE论文研读

KAZE是发表在ECCV2012的一种特征点检测算法,相比于SIFT和SURF,KAZE建立的高斯金字塔是非线性的尺度空间,采用加性算子分裂算法(Additive Operator Splitting, AOS)来进行非线性扩散滤波。一个很显著的特点是在模糊图像的同时还能保留边缘细节…

简单的线性模型实现tensorflow权重的生成和调用,并且用类的方式实现参数共享

首先看文件路径,line_regression是总文件夹,model文件夹存放权重文件, global_variable.py写了一句话. save_path./model/weight 权重要存放的路径,以weight命名. lineRegulation_model.py代码 import tensorflow as tf "…

comparing ORB and AKAZE

文章全称是《Comparing ORB and AKAZE for visual odometry of unmanned aerial vehicles》。这是一篇来自巴西的文章,没有在百度文库中找到,是在其他博客中给出的链接得到的。从链接的URL可以看出这是一篇来自会议CCIS云计算与智能系统国际会议的文章。…

利用 CRISPR 基因编辑技术,人类正在做七件“疯狂”的事

来源:36Kr编译:喜汤很少有哪种现代科学创新能像CRISPR基因编辑技术一样影响深远。有了它,科学家们可以精确地改变任何细胞的DNA。CRISPR技术成为新宠,部分原因是它比早期基因编辑技术更容易使用。尽管CRISPR还没有彻底大展身手&am…

吴恩达作业3:利用深层神经网络实现小猫的分类

利用4层神经网络实现小猫的分类,小猫训练样本是(209,64*64*312288),故输入节点是12288个,隐藏层节点依次为20,7,5,输出层为1。 首先看文件路径,dnn_utils_v2.py代码是激活…

A-KAZE论文研读

AKAZE是KAZE的加速版本。KAZE在构建非线性空间的过程中很耗时,在AKAZE中将Fast Explicit Diffusion(FED)加入到金字塔框架可以dramatically speed-up。在描述子方面,AKAZE使用了更高效的Modified Local Difference Binary(M-LDB),可以从非线性…

和你抢“饭碗”的40家服务机器人企业大盘点!

来源:物联网智库摘要:本文将对国内近40家服务机器人企业进行汇总介绍,所选企业在其相应版块活跃度较高。从三个大类进行了细分盘点。国家机器人联盟(IFR)根据应用环境将机器人分为了工业机器人和服务机器人。服务机器人…