Python单链表实现详解:从原理到代码实战

慢慢来
慢慢来
发布时间:2026-10-13| 3人浏览过
原创

本文深入解析线性表结构,对比顺序表与链表的存储差异。重点讲解Python中变量标识与指针机制,并基于类实现单链表、单向循环链表及双向链表的核心功能,包含插入、删除、查找等操作的代码示例与原理说明。

前言

线性表基础:顺序表与链式表

线性表作为最基础且简单的数据结构,其本质是一种一维的数据存储结构。

线性表主要包含两种形式:顺序表和链式表。

  • 顺序表采用地址连续的存储单元依次存放数据元素,这种结构被称为线性表的顺序存储或顺序映像。
  • 链式表则使用任意存储单元存放数据元素,称为链式存储结构。其存储单元可以是连续的,也可以是不连续的,主要依靠节点间的连接信息(指针)来构建逻辑关系。

*顺序表(非本文重点,仅作简要介绍)

顺序表通过连续存储单元存放数据,查找元素十分便捷。然而,插入和删除操作相对复杂。因为顺序表依赖地址连续性,删除元素后需将后续所有元素向前移动以填补空缺;插入元素时,则需先将该位置后的元素向后移动,腾出空间后再添加新元素。

以C语言为例,顺序表通常通过数组实现,创建数组即分配一块内存。除了静态空间分配,还支持动态扩展。后续操作涉及大量数组元素移动,导致时间复杂度较高。

在Python中,顺序表主要有两种表现形式:

  • 一体式结构
  • 分离式结构

这里的“一体”与“分离”指的是数据元素集合与维持正确操作所需的元信息(如长度、容量等)是存储在同一块内存空间中,还是分布在相邻的另一块独立空间中。

Python中的tuple和list均采用了顺序表的实现技术。其中,tuple是不可变的,不支持内部元素的修改操作;而list是元素个数可变的线性表,支持添加、删除等操作。list的实现思想与C语言类似,主要是对底层功能进行了封装,体现了list的各项属性特性。

*链式表

Python变量机制与链表指针实现

链表通过“链”连接相邻节点。在C语言中,指针通过地址定位目标对象。因此,链表节点不仅包含数据元素,还需包含指向下一个节点的地址信息。

这里涉及指针和地址的概念。在Python中,指针的表现形式有所不同。我们需要先理解Python变量标识的本质,再探讨指针域的实现方式。

首先观察为何变量a和b的id相同?进一步思考:在Python中交换两个变量的值是如何实现的?


1 a = 10
2 b = 20
3 a,b = b,a

为什么Python支持这种赋值方式?下面通过图示进一步解析。

 

现在是否理解了变量本质上是存储地址的标识?交换变量的值,实质上是修改变量的指向。明确了标识的含义后,链表中的指针域实现变得简单:只需将变量指向下一个节点即可。接下来的内容与常规链表无异,此处阐述旨在厘清Python建立链接的机制。

Python单链表代码实现

一、单链表

接下来通过类来实现一个节点,节点包含数据域和链接域。代码中实现了插入、查找等常用功能。本文重点在于展示单链表在Python中的具体运用。基于已有知识,可以方便地应用链表结构。后续代码不再赘述解释,建议读者仔细研读。如有疑惑欢迎留言,我将尽力详细回复。


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date  : 2018-06-12 11:23:21
# @Author : yudanqu (943775910@qq.com)
# @Link  : https://www.cnblogs.com/yudanqu/
# @Version : $Id$


class Node(object):
  """节点"""

  def __init__(self, elem):
    self.elem = elem
    self.next = None # 初始设置下一节点为空

'''
上面定义了一个节点的类,当然也可以直接使用python的一些结构。比如通过元组(elem, None)
'''


# 下面创建单链表,并实现其应有的功能


class SingleLinkList(object):
  """单链表"""

  def __init__(self, node=None): # 使用一个默认参数,在传入头结点时则接收,在没有传入时,就默认头结点为空
    self.__head = node

  def is_empty(self):
    '''链表是否为空'''
    return self.__head == None

  def length(self):
    '''链表长度'''
    # cur游标,用来移动遍历节点
    cur = self.__head
    # count记录数量
    count = 0
    while cur != None:
      count += 1
      cur = cur.next
    return count

  def travel(self):
    '''遍历整个列表'''
    cur = self.__head
    while cur != None:
      print(cur.elem, end=' ')
      cur = cur.next
    print("\n")

  def add(self, item):
    '''链表头部添加元素'''
    node = Node(item)
    node.next = self.__head
    self.__head = node

  def append(self, item):
    '''链表尾部添加元素'''
    node = Node(item)
    # 由于特殊情况当链表为空时没有next,所以在前面要做个判断
    if self.is_empty():
      self.__head = node
    else:
      cur = self.__head
      while cur.next != None:
        cur = cur.next
      cur.next = node

  def insert(self, pos, item):
    '''指定位置添加元素'''
    if pos <= 0:
        # 如果pos位置在0或者以前,那么都当做头插法来做
      self.add(item)
    elif pos > self.length() - 1:
      # 如果pos位置比原链表长,那么都当做尾插法来做
      self.append(item)
    else:
      per = self.__head
      count = 0
      while count < pos - 1:
        count += 1
        per = per.next
      # 当循环退出后,pre指向pos-1位置
      node = Node(item)
      node.next = per.next
      per.next = node

  def remove(self, item):
    '''删除节点'''
    cur = self.__head
    pre = None
    while cur != None:
      if cur.elem == item:
        # 先判断该节点是否是头结点
        if cur == self.__head:
          self.__head = cur.next
        else:
          pre.next = cur.next
        break
      else:
        pre = cur
        cur = cur.next

  def search(self, item):
    '''查找节点是否存在'''
    cur = self.__head
    while not cur:
      if cur.elem == item:
        return True
      else:
        cur = cur.next
    return False


if __name__ == "__main__":

    # node = Node(100) # 先创建一个节点传进去

  ll = SingleLinkList()
  print(ll.is_empty())
  print(ll.length())

  ll.append(3)
  ll.add(999)
  ll.insert(-3, 110)
  ll.insert(99, 111)
  print(ll.is_empty())
  print(ll.length())
  ll.travel()
  ll.remove(111)
  ll.travel()

单向循环链表与双向链表解析

二、单向循环链表和双向链表

与单链表相关的还有单向循环链表和双向链表:

单向循环链表:在单链表基础上,增加由尾节点指向首节点的链接。需注意区分“首节点”(第一个存储数据的节点)和“头结点”(仅含链接域、指向首节点的节点,不存储实际数据)。循环链表的某些功能(如判空、判满)与单链表不同,需根据循环特性调整判断逻辑。这些修改可基于前文单链表实现进行尝试。

双向链表:相比单链表,双向链表具备“双向”特性,既可从前往后遍历,也可从后往前遍历。方向由定义决定,一端为正向,另一端为反向。其实现与单链表基本一致。单链表在数据域外增加一个指向后继节点的链接域;双向链表则在此基础上,再增加一个指向前驱节点的链接域。创建链表时,需建立每个节点与前驱及后继节点的连接。

双向链表的插入和删除等操作需格外小心,避免丢失存储的地址信息。务必仔细考虑前后指向关系,明确先链接谁,再链接谁。

本文初衷仅讨论前述内容,但写作过程中觉得有必要补充后续部分,尽管尚未完全展开。读者可挑选有用部分阅读。

总结

以上为本文全部内容,希望这些内容对您的学习或工作具有参考价值。感谢对本站的支持。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。