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 小时前
2026-04-30 GitHub 热点项目精选
开发语言·程序员·github·代码托管
m0_613856292 小时前
mysql如何利用事务隔离级别解决特定业务冲突_mysql隔离方案选型
jvm·数据库·python
叶小鸡3 小时前
Java 篇-项目实战-苍穹外卖-笔记汇总
java·开发语言·笔记
AI人工智能+电脑小能手3 小时前
【大白话说Java面试题】【Java基础篇】第22题:HashMap 和 HashSet 有哪些区别
java·开发语言·哈希算法·散列表·hash
我的xiaodoujiao3 小时前
API 接口自动化测试详细图文教程学习系列16--项目实战演练3
python·学习·测试工具·pytest
ID_180079054733 小时前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
时空系4 小时前
第10篇:继承扩展——面向对象编程进阶 python中文编程
开发语言·python·ai编程
CHANG_THE_WORLD5 小时前
python 批量终止进程exe
开发语言·python
古城小栈5 小时前
从 cargo-whero 库中,找到提升 rust 的契机
开发语言·后端·rust
liann1195 小时前
3.2_红队攻击框架--MITRE ATT&CK‌
python·网络协议·安全·网络安全·系统安全·信息与通信