Python - 链表浅析

Python - 链表浅析

本篇用Python代码模拟链表

1. 链表介绍

概述

链表属于数据结构之 线性结构 的一种,每个节点都只能有 1个前驱1个后继 节点。

作用

  • 用于优化顺序表的弊端(如果没有足够的连续的内存空间,会导致扩容失败)。
  • 链表扩容时,有地儿就行,连不连续无所谓。

组成

节点 组成,其中节点由以下两部分组成:

  • 元素域 (数值域):存储数据。
  • 链接域 (地址域):存储下一个节点的地址。

分类

根据节点类型不同,链表主要分为:

  • 单向链表 :节点由1个数值域和1个地址域组成,前边节点的地址域存储的是后续节点的地址,最后1个节点的地址域为 None
  • 单向循环链表:尾节点的地址域指向头节点。
  • 双向链表:节点包含前驱指针和后继指针。
  • 双向循环链表 :双向链表的头尾相连。

2. 自定义代码模拟链表 - 思路分析

  1. NodeObj 类 (节点类)

    • item: 数值域 (元素域)
    • next: 地址域 (链接域)
  2. LinkedList 类 (链表类)

    • 属性 :
      • head: 表示头结点,指向第1个节点。
    • 行为 (方法) :
      • is_empty(): 判断链表是否为空
      • length(): 获取链表长度
      • travel(): 遍历整个链表
      • add(item): 链表头部添加元素
      • append(item): 链表尾部添加元素
      • insert(pos, item): 指定位置添加元素
      • remove(item): 删除节点
      • search(item): 查找节点是否存在
  3. 测试 : 在 main 模块中进行功能验证。


3. 代码实现

python 复制代码
# 1. 自定义 NodeObj 类,表示节点类
class NodeObj:
    # 初始化属性
    def __init__(self, item):
        self.item = item        # 元素域 (数值域)
        self.next = None        # 链接域 (地址域)


# 2. 自定义 LinkedList 类,表示链表
class LinkedList:
    # 1. 初始化属性
    def __init__(self, node=None):
        self.head = node      # 链表的头结点,指向第1个节点

    # 2. is_empty(self) 链表是否为空
    def is_empty(self):
        return self.head is None

    # 3. length(self) 链表长度
    def length(self):
        count = 0
        cur = self.head
        while cur is not None:
            count += 1
            cur = cur.next
        return count

    # 4. travel(self) 遍历整个链表
    def travel(self):
        cur = self.head
        items = []
        while cur is not None:
            items.append(str(cur.item))
            cur = cur.next
        print(" -> ".join(items))

    # 5. add(self, item) 链表头部添加元素
    def add(self, item):
        """头部插入,时间复杂度 O(1)"""
        node = NodeObj(item)
        node.next = self.head
        self.head = node

    # 6. append(self, item) 链表尾部添加元素
    def append(self, item):
        """尾部追加,时间复杂度 O(n)"""
        node = NodeObj(item)
        if self.is_empty():
            self.head = node
        else:
            cur = self.head
            while cur.next is not None:
                cur = cur.next
            cur.next = node

    # 7. insert(self, pos, item) 指定位置添加元素
    def insert(self, pos, item):
        """
        :param pos: 从0开始索引
        :param item: 插入的数据
        """
        if pos <= 0:
            self.add(item)
        elif pos > (self.length() - 1):
            self.append(item)
        else:
            node = NodeObj(item)
            count = 0
            pre = self.head
            # 移动到 pos 位置的前一个节点
            while count < (pos - 1):
                count += 1
                pre = pre.next
            # 执行插入
            node.next = pre.next
            pre.next = node

    # 8. remove(self, item) 删除节点
    def remove(self, item):
        cur = self.head
        pre = None
        while cur is not None:
            if cur.item == item:
                # 判断是否是头结点
                if pre is None:
                    self.head = cur.next
                else:
                    pre.next = cur.next
                return True # 删除成功
            else:
                pre = cur
                cur = cur.next
        return False # 未找到

    # 9. search(self, item) 查找节点是否存在
    def search(self, item):
        cur = self.head
        while cur is not None:
            if cur.item == item:
                return True
            cur = cur.next
        return False


# 3. 在 main 中测试
if __name__ == '__main__':
    print("--- 测试节点类 ---")
    # 3.1 测试节点类
    node1 = NodeObj(10)

    # 3.2 打印当前节点的 元素域 (数值域) 和 链接域 (地址域)
    print(f'元素域 (数值域): {node1.item}')    # 10
    print(f'链接域 (地址域): {node1.next}')    # None
    print(f'node1 对象: {node1}')            # 地址值
    print(f'node1 的类型: {type(node1)}')
    print('-' * 20)

    print("\n--- 测试链表类 ---")
    # 3.2 测试链表类
    my_linkedlist = LinkedList(node1)
    print(f'头结点为:{my_linkedlist.head}')
    print(f'头结点的元素域:{my_linkedlist.head.item}')    # 10
    print(f'头结点的地址域:{my_linkedlist.head.next}')    # None
    
    print("\n--- 功能测试 ---")
    # 测试是否为空
    print(f"链表是否为空:{my_linkedlist.is_empty()}")
    print(f"链表长度:{my_linkedlist.length()}")
    
    # 遍历
    print("当前链表内容:", end="")
    my_linkedlist.travel()
    
    # 头部添加
    my_linkedlist.add(20)
    print("头部添加 20 后:", end="")
    my_linkedlist.travel()
    
    # 尾部添加
    my_linkedlist.append(30)
    print("尾部添加 30 后:", end="")
    my_linkedlist.travel()
    
    # 指定位置插入
    my_linkedlist.insert(1, 25)
    print("位置 1 插入 25 后:", end="")
    my_linkedlist.travel()
    
    # 查找
    print(f"查找 25 是否存在:{my_linkedlist.search(25)}")
    print(f"查找 100 是否存在:{my_linkedlist.search(100)}")
    
    # 删除
    my_linkedlist.remove(25)
    print("删除 25 后:", end="")
    my_linkedlist.travel()
    
    print(f"最终链表长度:{my_linkedlist.length()}")
相关推荐
翻斗包菜1 分钟前
Python 网络编程从入门到精通:TCP/UDP/Socket 实战详解
网络·python·tcp/ip
七颗糖很甜13 分钟前
雨滴谱数据深度解析——从原始变量到科学产品的Python实现【下篇】
python·算法·pandas
独特的螺狮粉14 分钟前
开源鸿蒙跨平台Flutter开发:喝水时间提醒应用
开发语言·flutter·华为·信息可视化·开源·harmonyos·鸿蒙
爱码小白15 分钟前
MySQL 常用数据类型的系统总结
数据库·python·算法
xcbrand18 分钟前
专精特新品牌全案公司有哪些
大数据·人工智能·python
橘子编程23 分钟前
GoF 23 种设计模式完整知识总结与使用教程
java·c语言·开发语言·python·设计模式
玖釉-26 分钟前
告别 Shared Memory 瓶颈:Vulkan Subgroup 架构解析与硬核实战指南
开发语言·c++·windows·图形渲染
枫叶林FYL26 分钟前
【Python高级工程与架构实战】项目五:生产级LLM Agent框架:基于PydanticAI的类型安全企业级实现
python·安全·架构
ths51226 分钟前
Python 正则表达式学习笔记(小白超详细版)(一)
python·正则表达式
lly20240627 分钟前
SQL UPDATE 语句详解
开发语言