昨天考研专业课遇到了一个选择题 带头结点的单链表具有什么优点 ,因为平时都是用的带头节点的链表,只是单纯记住了结论。考后我想仔细研究研究这个问题... 来CSDN找点资料,发现越看越模糊,下面我来总结总结。
1.让我们先来瞅瞅这个《王道考研》辅导书上给的结论:
下图就是一个带头结点的单链表:


2.这是《大话数据结构》上给的结论:
3.CSDN上的一些结论:
①.使用头节点,指针域都是指向第一个结点,对于空表和非空表操作都是一致的,对于第一个元素的操作(添加、删除)更加方便。
②使用头节点,则第一个位置的插入和删除都是对 head->next (head是头指针) 操作,而不是head本身,而且减少了算法分支 (if else 分支)。
4.我的理解:
头指针:
①.用来标记链表,做链表的名字。
②.指向链表的第一个结点。
头结点:
①.统一操作(第一个结点的插入、删除)。
②.统一空表和非空表。
首元节点:
①.第一个具有实际意义(存了值)的点。
记住结论很轻松,但是真考试的时候,要你做选择的时候,往往因为缺少操作而没有底气,是谓“知其然,不知其所以然。” 回头看的时候还真发现自己没有整清楚。
定义结点:
①有头节点初始化及插入(头插法)操作

②无头节点初始化及其头插法(简写)
③有头节点初始化及尾插法

④无头节点初始化及其尾插法
乍一看没问题,但是仔细斟酌,你会发现已经找不到了,始终指向空,而又一直指向尾结点,导致了一个结果:即使这些结点连在一起,但是我们已经找不到他们了。就好比你只认识狼王和他的小弟,狼王老年痴呆,他小弟又在最后面,你也没有办法挨个遍历整个狼群。那么有头结点的尾插法,为什么L就不会丢失呢:因为始终指向的是头结点,这“头节点”好比狼王的亲儿子,虽然狼王老年痴呆但是他肯定记得他的亲儿子,让狼王和他儿子直接对接,那么你仍然可以遍历整个狼群。所以那么我们该怎么写无头节点的尾插法呢?自然就是没有头节点,把第一个结点就设置为头节点。`
①有头节点“从头部”删除整个单链表
我们先理清楚几个结点:是头指针,指向头节点,是首元结点。
这里为什么要多一个q呢?直接 不香吗?这也是我曾犯过的错误,后头我想了个例子:皇帝驾崩之前,肯定要立遗嘱,记录下把位置传给那个儿子,不可能皇帝死了后诈尸,起来宣布把皇位传给谁。这个p除了有数据域,还有指针域,你在做时候,整个结点就没了,它指向谁也不知道了,所以要提前记录下来。
②不带头节点“从头部”删除整个单链表
这里的L直接指向了第一个首元结点:
经过比较我们发现:有无头结点对删除整个单链表操作,似乎没有带来便利,那么我们需要进一步探讨: 下面我们来探讨,带头结点是否对删除单链表单个元素操作,提供了便利:
③带头节点删除单个单链表元素:
为了和删除整个单链表操作区分,我们假定删除单链表中的第二个元素。(实际操作中我们可以根据值、下标等找到需要删除的元素)

④不带头节点“从尾部”删除整个单链表
这里的不带头结点,所以 指向首元结点,是第二个结点。那么我们这样操作:
这时候我们发现该代码缺少了一种情况:为的时候,也就是我们删除第二个点的时候,我们要让第一个结点,指向第三个结点,而这里我们只能操作第二个点。所以我们又需要动用来完善这种情况:
经过上面一系列的折腾,我们在此发现了带头结点是如何具有统一链表操作。
我觉得我写的太啰嗦并且代码过于简陋,所以需要详细一点的代码大家可以,看看这个小哥的代码:不秃头的小黄人
①那么显而易见表空和表非空,显然也是在第一个结点做文章。判断是否为空:
|带头结点|不带头节点 |
|--|--|
| L->next=NULL| L=NULL |
②我们再来回顾下两者之间的区别:
若使用头结点,无论表是否为空,头指针都指向头结点,对于空表和非空表的操作是一致的。
若不使用头结点,当表非空时,头指针指向第1个结点的地址,但是对于空表,头指针指向的是NULL,此时空表和非空表的操作是不一致的。
③我们惊人发现,其实在上面的尾插法中,我们已经体现出了这一特点,不妨回过头来看看:
带头结点:
不带头结点:
结果显而易见,不带头结点的确实要多一步判断是否为空操作
话不多说,我们再来看看这个结论:
当然实际情况实际要实际分析。不能关背结论,更不能背代码。面对疑惑希望我们保持刨根问底的精神。
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qkl-jc/20387.html