python 链表中头结点的含义以及引入头结点的作用

一、概念

头结点:是虚拟出来的一个结点,不保存数据。头结点的next指针指向链表中的第一个节点。对于头结点,数据域可以不存储任何信息,也可存储如链表长度等附加信息。头结点不是链表所必需的。

头指针:是指向第一个结点的指针,如果链表没有引入头结点,那么头指针指向链表的第一个结点。头指针是链表所必需的。

[注意]有头结点,头指针指向头结点;没有头结点,头指针指向链表第一个结点,如果链表为空,头指针为NULL

二、为何引入头结点

  1. 防止头指针为NULL,有头结点,头指针始终指向头结点,那么无论链表是否为空,头指针均不为空;没有头结点,头指针就为NULL

  2. 插入/删除第一个结点时不需要修改头指针,只需要改变 头结点.next

  3. 有头结点时,插入/删除第一个结点时,空链表/非空链表操作逻辑一致,不需要额外判断

 

带头结点的单链表

 

不带头结点的单链表 

三、单链表的创建(带头结点和不带头结点两种实现方式)

下面代码中头插法的两种实现方式可以佐证标题二中2、3两点,带头结点时不需要修改头指针,且空链表/非空链表的插入逻辑一致

if __name__ == '__main__':
    # 初始化链表
    class Node:
        def __init__(self, item):
            self.item = item
            self.next = None


    # 链表的创建
    # 头插法:不使用头结点
    def create_linklist_head(li):
        if li == []:
            return None
        head = Node(li[0])  # 链表为空时,头指针指向第一个结点
        for element in li[1:]:  # 链表不为空时,要插入的结点.next指向头指针的结点,再修改头指针为新插入的结点
            node = Node(element)
            node.next = head
            head = node  # 头指针不断移动
        return head


    # 链表的创建
    # 头插法:使用头结点
    def create_linklist_head2(li):
        head = Node(None)  # 头结点
        for element in li:
            node = Node(element)
            node.next = head.next
            head.next = node
        return head.next


    # 尾插法:不使用头结点
    def create_linklidt_tail(li):
        if li == []:
            return None
        head = Node(li[0])  # 链表为空时,头指针指向第一个结点
        tail = head  # 尾指针指向同一个内存地址
        for element in li[1:]:  # 链表不为空时,尾结点.next指向新插入的结点,尾指针指向新插入的结点
            node = Node(element)
            tail.next = node
            tail = node  # 尾指针不断移动
        return head


    # 尾插法:使用头结点
    def create_linklidt_tail2(li):
        head = Node(None)  # 头结点
        tail = head  # 尾指针指向同一个内存地址
        for element in li:
            node = Node(element)
            tail.next = node
            tail = node  # 尾指针不断移动
        return head.next


    # 遍历输出链表:
    def print_linklist(li):
        while li:
            print(li.item, end=',')
            li = li.next
        print(end='\n')


    li = create_linklist_head([1, 2, 3, 6, 8])
    print("不带头结点-头插法:")
    print_linklist(li)
    li2 = create_linklist_head2([1, 2, 3, 6, 8])
    print("带头结点-头插法:")
    print_linklist(li2)
    lk = create_linklidt_tail([1, 2, 3, 6, 8])
    print("不带头结点-尾插法:")
    print_linklist(lk)
    lk2 = create_linklidt_tail2([1, 2, 3, 6, 8])
    print("带头结点-尾插法:")
    print_linklist(lk2)

参考文章:

头结点的含义以及引入头结点的作用_snow_7的博客-CSDN博客_头结点

  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值