从头开始:为什么线性表需要头节点?

什么是线性表?

(可以看我之前的数据结构专题一:数据结构(C/C++)专题一:顺序表与链表-CSDN博客

线性表是一种数据结构,其中的元素按线性顺序排列。常见的线性表包括数组和链表。

  • 数组:元素在内存中是连续存放的,可以通过索引直接访问。
  • 链表:元素在内存中不一定是连续存放的,每个元素(称为节点)包含数据和指向下一个节点的指针。

什么是头节点?

头节点是链表中的一个特殊节点,它通常位于链表的开头。头节点本身不一定存储实际数据(也可以存储数据),但它的主要作用是指向链表的第一个实际节点。

优点

为什么需要头节点?

  1. 统一处理边界情况

  2. 简化代码

  3. 容易实现一些特殊操作

 1.统一处理边界情况

无头结点时处理链表的第一个节点和其他节点的操作(如插入、删除)会有所不同。例如,删除第一个节点需要更新链表的头指针,而删除其他节点不需要。

首先,我们举个例子以单链表的角度:

没有头节点的链表操作

插入操作

假设我们有一个没有头节点的链表,链表结构如下:

链表:1 -> 2 -> 3 -> NULL

在第一个节点前插入新节点:

  • 目标:在第一个节点前插入节点0。
  • 操作步骤:
  1. 创建新节点0。
  2. 将新节点0的next指针指向当前第一个节点1。
  3. 更新链表头指针指向新节点0。

插入后的链表:

链表:0 -> 1 -> 2 -> 3 -> NULL

在中间某个节点后插入新节点

  • 目标:在节点2后插入节点4
  • 操作步骤:
  1. 找到节点2
  2. 创建新节点4
  3. 将新节点4next指针指向节点2next指针(即节点3)。
  4. 将节点2next指针指向新节点4
链表:0 -> 1 -> 2 -> 4 -> 3 -> NULL

有头节点的链表操作

假设我们有一个有头节点的链表,链表结构如下:

链表:Head -> 1 -> 2 -> 3 -> NULL
插入操作
  1. 在第一个节点前插入新节点

    • 目标:在第一个节点前插入节点0
    • 操作步骤:
      1. 创建新节点0
      2. 将新节点0next指向头节点的next(即节点1)。
      3. 将头节点的next指向新节点0

    插入后的链表:

    链表:Head -> 0 -> 1 -> 2 -> 3 -> NULL

  2. 在中间某个节点后插入新节点

    • 目标:在节点2后插入节点4
    • 操作步骤:
      1. 找到节点2
      2. 创建新节点4
      3. 将新节点4next指向节点2next(即节点3)。
      4. 将节点2next指向新节点4

    插入后的链表:

    链表:Head -> 0 -> 1 -> 2 -> 4 -> 3 -> NULL

关于删除,也是同理,如果没有头结点时,删除首元节点是,要处理头指针L 

删除第一个节点

  • 目标:删除第一个节点0
  • 操作步骤:
    1. 更新链表头指针指向第一个节点的next指针(即节点1)。
链表:1 -> 2 -> 4 -> 3 -> NULL

删除中间某个节点

  • 目标:删除节点2
  • 操作步骤:
    1. 找到节点2的前一个节点(即节点1)。
    2. 将节点1next指针指向节点2next指针(即节点4
链表:1 -> 4 -> 3 -> NULL

有头节点

链表:Head -> 0 -> 1 -> 2 -> 4 -> 3 -> NULL

删除第一个实际节点

  • 目标:删除第一个实际节点0
  • 操作步骤:
    1. 将头节点的next指向第一个实际节点0next(即节点1)。
链表:Head -> 1 -> 2 -> 4 -> 3 -> NULL

删除中间某个节点

  • 目标:删除节点2
  • 操作步骤:
    1. 找到节点2的前一个节点(即节点1)。
    2. 将节点1next指向节点2next(即节点4)。
链表:Head -> 1 -> 4 -> 3 -> NULL

通过上面的例子可以看出,在没有头节点的情况下,处理链表的第一个节点和其他节点的操作是有所不同的,特别是在插入和删除第一个节点时,需要单独处理头指针。而在有头节点的情况下,所有节点的操作都可以统一处理,头节点前面始终有一个“虚拟”的节点,使得第一个实际节点的处理与其他节点一致,从而简化了代码逻辑。 

2.简化代码 

什么是空表和非空表的统一处理?

空表指的是链表中没有任何实际节点,而非空表指的是链表中至少有一个实际节点。在没有头节点的情况下,我们需要分别处理空表和非空表的插入和删除操作,而有了头节点之后,这些操作就可以统一处理。

没有头节点的链表

插入操作
  1. 插入到空表

    如果链表为空(即头指针为NULL),我们插入一个新节点:

    原链表:NULL
    
    • 操作步骤:
      1. 创建新节点1
      2. 将链表的头指针指向新节点1

    插入后的链表:

    链表:1 -> NULL
    
  2. 插入到非空表

    如果链表非空(如头指针指向节点1),在第一个节点前插入新节点0

     

    原链表:1 -> 2 -> 3 -> NULL

    • 操作步骤:
      1. 创建新节点0
      2. 将新节点0next指向当前第一个节点1
      3. 将链表的头指针指向新节点0

    插入后的链表:

    链表:0 -> 1 -> 2 -> 3 -> NULL
    
删除操作
  1. 删除空表中的节点

    如果链表为空,尝试删除节点会导致错误,需要检查链表是否为空:

    原链表:NULL
    
    • 操作步骤:
      1. 检查链表头指针是否为NULL,如果是,直接返回,不做任何操作。
  2. 删除非空表中的第一个节点

    如果链表非空(如头指针指向节点1),删除第一个节点:

    原链表:1 -> 2 -> 3 -> NULL
    
    • 操作步骤:
      1. 将链表的头指针指向第一个节点的next(即节点2)。

    删除后的链表:

    链表:2 -> 3 -> NULL
    

有头节点的链表

在有头节点的链表中,空表和非空表的操作都可以统一处理。头节点的next指针始终指向链表的第一个实际节点,若链表为空,则头节点的nextNULL

插入操作
  1. 插入到空表

    如果链表为空(即头节点的nextNULL),我们插入一个新节点:

    原链表:Head -> NULL
    
    • 操作步骤:
      1. 创建新节点1
      2. 将头节点的next指向新节点1

    插入后的链表:

    链表:Head -> 1 -> NULL
    
  2. 插入到非空表

    如果链表非空(如头节点的next指向节点1),在第一个节点前插入新节点0

    原链表:Head -> 1 -> 2 -> 3 -> NULL
    
    • 操作步骤:
      1. 创建新节点0
      2. 将新节点0next指向头节点的next(即节点1)。
      3. 将头节点的next指向新节点0

    插入后的链表:

    链表:Head -> 0 -> 1 -> 2 -> 3 -> NULL
    
删除操作
  1. 删除空表中的节点

    如果链表为空,头节点的nextNULL

    原链表:Head -> NULL
    
    • 操作步骤:
      1. 检查头节点的next是否为NULL,如果是,直接返回,不做任何操作。
  2. 删除非空表中的第一个节点

    如果链表非空(如头节点的next指向节点1),删除第一个节点:

    原链表:Head -> 1 -> 2 -> 3 -> NULL
    
    • 操作步骤:
      1. 将头节点的next指向第一个节点的next(即节点2)。

    删除后的链表:

    链表:Head -> 2 -> 3 -> NULL
    

总结

有了头节点之后,无论链表是空的还是非空的,插入和删除操作都可以统一处理,简化了代码逻辑。在操作之前,不需要分别检查链表是否为空,只需对头节点的next进行操作。这样不仅提高了代码的可读性和可维护性,也减少了出错的机会。

3.容易实现一些特殊操作 

  • 头节点可以用来存储链表的元信息,例如链表的长度。这在进行一些需要知道链表长度的操作时会很方便。
  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lidiyscrp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值