Python实现单向链表

本文详细介绍了如何使用Python实现单向链表,包括创建链表节点、判断链表是否为空、添加元素(如连接节点、插入节点、合并链表)、删除元素、计算链表长度、修改元素值以及遍历链表等操作。通过一系列步骤和示例代码展示了单向链表的数据结构和操作方法。
摘要由CSDN通过智能技术生成

目录

链表

单向链表

建立单向链表

创建单向链表节点

头节点

创建单向链表 

链表是否为空

添加元素

连接两个节点

插入单个节点

 将节点插入到链表末尾

插入一个元素到指定索引

合并其它单向链表

销毁链表

删除元素

删除链表的第一个元素

删除链表的最后一个元素

删除链表中指定值的元素

删除链表中指定值的全部元素

计算链表长度

修改元素值

替换元素值

修改某个索引的值

遍历线性表

完整代码


 

链表

链表是由许多数据项按特定顺序排列而成的线性表。链表的特性是其各个数据项在计算机内存中的位置是不连续且随机存放的。其优点是数据的插入和删除都相当方便,有新数据加入就向系统申请一块内存空间,而数据被删除后,就可以把这块内存空间还给系统,加入和删除都不需要移动大量数据。其缺点是设计数据结构较为麻烦,另外在查找数据时,无法像列表、元组等静态数据结构那样可随机读取数据,必须按序查找到该数据为止。

 

单向链表

在动态分配内存空间时,最常使用的就是单向链表。一个单向链表节点由两部分组成,一部分是数据元素(数据元素可以是多个),另一部分是指针。数据元素保存业务数据,指针指向下一个元素在内存中的地址。在单向链表中,第一个节点表示头节点。头节点可以不用来保存业务数据,仅仅用来作为链表的表头,最后一个节点的指针为None。

由于单向链表中的所有节点都知道节点本身的下一个节点在哪里,但是对于前一个节点却没有办法知道,因此在单向链表的各种操作中,“链表表头”显得相当重要。只要存在链表头,就可以遍历、操作整个链表。除非必要,否则不可移动链表表头。

 

建立单向链表

创建单向链表节点

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

每一个单向链表节点就是Node类的一个实例化对象。其中value表示节点的数据部分,根据实际业务数据部分可以是多个,数据类型也是根据实际业务来定。next表示节点的下一个指向节点,默认是空。

 

头节点

前面说过,单向链表的操作都依赖于头节点,因此找到了头节点就相当于找到了该单向链表。头节点本身的数据结构于其他节点并没有什么区别,它们都是Node类实例化出来的对象。在通常的使用中,为了操作方便和简化,可以将头节点视为单向链表的操作对象,而不是作为存储业务数据的一个节点,即头节点head的数据部分不存储任何值,仅仅指向下一个节点(可以理解为头节点就是火车的车头,车头不会搭载乘客,仅仅是为了控制火车)。

一个链表有且只有一个头节点和0个或多个数据节点,当链表只存在一个头节点而不存在任何数据节点时,该链表是一个空链表(即头节点的next值为None)。

 

创建单向链表 

总结完上面的知识,我们可以创建一个单向链表了。创建一个单向链表本质上就是创建一个头节点。

class LinkedList(object):
    def __init__(self):
        self.head = Node("head")

通过对LinkedList类实例化得到一个空的单向链表:我们在向上封装一层函数,用来创建一个空的单向链表:

def create() -> LinkedList:
    return LinkedList()

 

链表是否为空

如果一个链表只存在头节点,我们认为该链表是一个空链表。在LinkedList类中定义一个方法empty(),用来判断链表是否为空:

class LinkedList(object):
    def __init__(self):
        self.head = Node("head")
        
    def empty(self) -> bool:
        return self.head.next is None

 

添加元素

连接两个节点

链表是由若干个节点连接而成的。给列表中添加元素最基本的功能就是连接两个节点。对于两个节点A,B,我们将A.next = B即将A的下一个节点指向了B,也就是说B节点成为了A的下一个节点。

A.next = B

 我们在节点Node类里重写__add__方法来连接两个链表,简化代码:

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

重写__add__方法后两个节点的连接语法被我们简化了:

a = Node("A")
b = Node("B")
a + b

即直接使用 “+”运算符即可连接两个节点。a + b表示将b节点作为a节点的下一个节点。 

 

插入单个节点

通常便捷的插入方式是将新的节点插入到头节点的下一个位置。如果链表只有头节点,那么将新插入的节点作为头节点的下一个节点即可。如果链表有多个节点,那么需要将头节点的下一个节点指向新节点,同时新节点的下一个节点指向插入前头节点的下一个节点。即:

链表只存在头节点:

插入前,头指针指向None

插入后,头指针指向新节点,新节点作为链表尾部指向None:

 

链表存在多个节点:

插入前,链表头指针指向着其他节点:

插入后,头指针指向新节点,新节点指向Node1:

 

下面我们使用代码来实现上面的逻辑图:

    linked = create()

    # linked list only has head node
    newNode = Node("Python")
    linked.head.next = newNode

    # head -> Python -> [None]
    newNode = Node("C")
    ptr = linked.head.next
    linked.head.next = newNode
    newNode.next = ptr

 

根据上面的逻辑,我们在LinkedList类中封装一个add方法用来表示添加新的节点:

class LinkedList(object):
    def __init__(self):
        self.head = Node("head")

    def empty(self) -> bool:
        return self.head.next is None

    def add(self, node):
        if self.empty():
            self.head + node
        else:
            ptr = self.head.next
            self.he
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值