为了账号安全,请及时绑定邮箱和手机立即绑定

初学者必看:链表基础知识详解

概述

链表是一种通过节点和指针构成的数据结构,每个节点包含数据和指向下一个节点的引用,形成链式结构。链表在插入、删除和遍历操作上具有灵活性,弥补了数组在动态内存分配上的不足。本文详细介绍了链表的基本概念、类型、操作以及应用场景。

链表的基本概念与优缺点

链表是一种常见的数据结构,它通过节点(node)来存储数据。每个节点包含两部分:一部分存储数据,另一部分存储指向下一个节点的引用(或指针)。链表中的节点是通过指针链接在一起的,形成一个链式结构。链表的引入有效地解决了数组在动态内存分配中的不足,同时提供了灵活的插入、删除和遍历操作。

链表和数组相比,有以下几点不同:

  1. 存储方式:数组是连续的内存,而链表中的节点则是分散在内存中。
  2. 插入和删除操作:数组在插入或删除元素时需要移动其他元素,而链表只需修改指针即可。
  3. 内存分配:数组需要预分配固定的内存,链表节点可以动态分配,更加灵活。

优点

  1. 动态内存分配:链表中的节点可以动态分配,不需要预先确定大小。
  2. 插入和删除方便:在链表的任意位置插入或删除元素只需修改指针,不需要移动其他元素。
  3. 灵活的内存使用:每个节点只占用所需的空间,没有多余的空间浪费。

缺点

  1. 内存利用率低:由于每个节点都需要存储指针,所以链表的内存利用率相对较低。
  2. 随机访问困难:链表中的元素无法通过索引直接访问,必须从头开始逐个遍历。
  3. 额外的存储开销:每个节点存储的指针需要额外的空间,增加了内存的使用。

链表的类型

链表可以根据节点间的连接方式分为几种类型,包括单链表、循环链表和双向链表。

单链表

单链表是最简单的一种链表结构,每个节点只包含一个指针,指向下一个节点。单链表的数据结构定义如下:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class SingleLinkedList:
    def __init__(self):
        self.head = None

    def insert_at_head(self, value):
        new_node = Node(value)
        new_node.next = self.head
        self.head = new_node

    def insert_at_tail(self, value):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = new_node

循环链表

循环链表是一种特殊的链表,它的最后一个节点的next指针指向链表的第一个节点,形成一个闭环。这样可以实现循环遍历,循环链表的数据结构定义如下:

class CircularLinkedList:
    def __init__(self):
        self.head = None

    def insert_at_tail(self, value):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
            new_node.next = self.head
        else:
            current = self.head
            while current.next != self.head:
                current = current.next
            current.next = new_node
            new_node.next = self.head

双向链表

双向链表允许节点的双向访问,每个节点包含两个指针:一个指向前一个节点(prev),另一个指向后一个节点(next)。双向链表的数据结构定义如下:

class DoublyLinkedList:
    def __init__(self):
        self.head = None

    def insert_at_head(self, value):
        new_node = Node(value)
        new_node.next = self.head
        if self.head:
            self.head.prev = new_node
        self.head = new_node

    def insert_at_tail(self, value):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = new_node
            new_node.prev = current

如何在链表中插入节点

在链表中插入节点可以通过多种方式实现:插入头部、插入尾部或插入中间位置。下面是具体的插入操作实现。

在链表头部插入节点

在链表头部插入节点是十分简单直接的操作,只需要把新节点的next指针指向当前的头部节点,并把新节点设为新的头部即可。

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class SingleLinkedList:
    def __init__(self):
        self.head = None

    def insert_at_head(self, value):
        new_node = Node(value)
        new_node.next = self.head
        self.head = new_node

在链表尾部插入节点

在链表尾部插入节点需要遍历整个链表,找到最后一个节点,然后将新节点插入到其后。如果链表为空,则新节点将成为链表的唯一节点。

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class SingleLinkedList:
    def __init__(self):
        self.head = None

    def insert_at_tail(self, value):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = new_node

在链表中间插入节点

在链表中间插入节点需要找到目标位置的前一个节点,然后将新节点插入到其后,并将前一个节点的next指针指向新节点,同时新节点的next指针指向原目标位置的节点。

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class SingleLinkedList:
    def __init__(self):
        self.head = None

    def insert_at_position(self, value, position):
        new_node = Node(value)
        if position == 0:
            new_node.next = self.head
            self.head = new_node
            return

        current = self.head
        index = 0
        while current and index < position - 1:
            current = current.next
            index += 1

        if current:
            new_node.next = current.next
            current.next = new_node

如何在链表中删除节点

在链表中删除节点可以通过删除头部、删除尾部或删除中间节点实现。下面是具体的删除操作实现。

删除链表头部节点

删除链表头部节点只需将头部指针指向当前头部的下一个节点即可。如果链表只有一个节点,删除后链表将变为空。

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class SingleLinkedList:
    def __init__(self):
        self.head = None

    def delete_at_head(self):
        if self.head:
            self.head = self.head.next

删除链表尾部节点

删除链表尾部节点需要遍历链表,找到倒数第二个节点,然后将它的next指针设为空。如果链表只有一个节点,则删除后链表将变为空。

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class SingleLinkedList:
    def __init__(self):
        self.head = None

    def delete_at_tail(self):
        if self.head is None:
            return

        if self.head.next is None:
            self.head = None
            return

        current = self.head
        while current.next.next:
            current = current.next
        current.next = None

删除链表中间节点

删除链表中间节点需要找到目标节点的前一个节点,然后将前一个节点的next指针指向目标节点的下一个节点。如果目标节点没有下一个节点,则前一个节点的next指针设为空。

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class SingleLinkedList:
    def __init__(self):
        self.head = None

    def delete_at_position(self, position):
        if position == 0:
            if self.head:
                self.head = self.head.next
            return

        current = self.head
        index = 0
        while current and index < position - 1:
            current = current.next
            index += 1

        if current and current.next:
            current.next = current.next.next

如何遍历链表

遍历链表有两种方式:从头到尾遍历和从尾到头遍历。

从头到尾遍历链表

从头到尾遍历链表是最常用的方式,只需要从链表的头部开始,沿着每个节点的next指针逐个访问每个节点。

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class SingleLinkedList:
    def __init__(self):
        self.head = None

    def traverse(self):
        current = self.head
        while current:
            print(current.value)
            current = current.next

从尾到头遍历链表

从尾到头遍历链表可以通过逆序遍历实现。通常的做法是将链表存储在一个额外的数据结构中(如列表),然后从后向前遍历这个数据结构。

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class SingleLinkedList:
    def __init__(self):
        self.head = None

    def traverse_reverse(self):
        nodes = []
        current = self.head
        while current:
            nodes.append(current)
            current = current.next

        for node in reversed(nodes):
            print(node.value)

链表的应用场景

链表由于其灵活的插入、删除和遍历操作,在许多编程场景中有广泛的应用。

数据结构中的应用

链表可以作为其他复杂数据结构(如链栈、链队列、哈希链表等)的基础。例如,链栈和链队列的实现可以基于单链表或双向链表,而哈希链表则利用链表解决哈希冲突问题。

其他编程中的应用

链表在其他编程场景中的应用也很广泛。例如,在文本编辑器中,链表可以用来实现文本的增删操作。在内存管理中,链表可以用来管理分配的内存块。在操作系统中,链表用于实现进程队列和文件系统缓冲区管理等。

链表作为一种基础而灵活的数据结构,其应用范围广泛,能够满足各种不同的需求。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消