python实现 单链表

本文详细介绍了链表这一动态数据结构的基础概念与实现方法,并通过Python代码演示了链表的创建、增删改查等基本操作,同时深入探讨了链表反转、回文判断及按k-group反转等高级技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、什么是链表?

链表是一种动态数据结构,它是用一组任意的存储单位存放数据元素。链表中的每一个元素成为”结点”,每个结点都是由数据域和指针域组成。它与数组有如下不同点:

  1. 数组需要预先定义大小,无法适应数据动态地增减,数据小于定义长度会浪费内存,超过则会无法插入。而链表是动态增删,可以随意增加。
  2. 数组对于元素查找很方便,直接get索引即可。链表获取元素则需要从头开始寻找,但是对于增删元素,直接修改结点指向即可,相对于数组更简单。
  3. 数组从栈中分配空间,链表中堆中分配空间,自由度大当管理麻烦。

二、链表基本方法实现(python)

1、初始化链表

"""结点类"""

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

def __init__(self):
    """初始化链表"""
    self.head = None

2、获取链表长度

def __len__(self):
    pre = self.head
    length = 0
    while pre:
        length += 1
        pre = pre.next
    return length

3、追加结点

如果head结点不存在,当前结点为head结点,否则找到尾结点,将尾结点的next指向当前结点(可以添加head和tail两个结点,就不需要寻找尾结点了)

"""追加结点"""

def append(self, x):
    """
    1、head为none:head-->node
    2、tail.next-->node
    """
    node = Node(x)
    if self.head is None:
        self.head = node
    else:
        pre = self.head
        while pre.next:
            pre = pre.next
        pre.next = node

4、获取结点

即判断index值的正负

def get(self, index):
    index = index if index >= 0 else len(self) + index
    if len(self) < index or index < 0:
        return None
    pre = self.head
    while index:
        pre = pre.next
        index -= 1
    return pre

5、设置结点

找到当前结点赋值即可

"""设置结点"""

def set(self, index, x):
    node = self.get(index)
    if node:
        node.x = x
    return node

6、插入结点

插入结点要找到插入位置的前一个结点,然后将前一结点的next指向当前结点,当前结点的next指向下一结点。

"""插入结点"""

def insert(self, index, x):
    """
    1、index 插入结点位置 包括正负数
    2、找到 index-1 --> pre_node 的结点
    3、 pre_node.next -->node
        node.next-->pre_node.next.next
    4、head
    """
    node = Node(x)
    if abs(index + 1) > len(self):
        return False
    index = index in index >= 0 else len(self) + index + 1
    if index == 0:
        node.next = self.head
        self.head = node
    else:
        pre = self.get(index - 1)
        if pre:
            next = pre.next
            pre.next = node
            node.next = next
        else:
            return Fasle
    return node

7、删除结点

删除结点,也要区分索引正负。找到当前结点前一个pre_node和后一个next_node, 将pre_node.next–>next_node 即可

"""删除某个元素"""

def del(self, index):
    f = index in index > 0 else abs(index + 1)
    if len(self) <= f:
    return False
    pre = self.head
    index = index if index >= 0 else len(self) + index
    prep = None
    while index:
        prep = pre
        pre = pre.next
        index -= 1
    if not prep:
        self.head = pre.next
    else:
        prep.next = pre.next
    return pre.x ###

8、反转链表

反转链表就是将node.next–>pre_node 递归实现即可,然后将tail 赋值为head

"""反转链表"""

def __reversed__(self):
    """
    1、pre-->next 转为next-->pre
    2、pre 若是head 则把pre.next--> None
    3、tail-->self.head
    """
    def reverse(pre_node, node):
        if pre_node is self.head:
            pre_node.next = None
        if node:
            next_node = node.next
            node.next = pre_node
            return reverse(node, next_node)
        else:
            self.head = pre_node
    return reverse(self.head, self.head.next)



# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        prev = None
        if not head:
            return head
        while head:
            cur = head
            head = head.next
            cur.next = prev
            prev = cur
        return cur

9、判断回文链表

time:O(n) space: O(1)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def isPalindrome(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        p1 = p2 = head
        res = None
        while p1 and p1.next:
            p1 = p1.next.next
            res, res.next, p2 = p2, res, p2.next
        if p1:
            p2 = p2.next
        while res and res.val == p2.val:
            res, p2 = res.next, p2.next
        return not res

10、leetcode_25.按k-group反转链表的结点

比如:给定链表: 1->2->3->4->5
当 k = 2, 返回: 2->1->4->3->5
当 k = 3, 返回: 3->2->1->4->5
代码如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        dummy = jump = ListNode(0)
        dummy.next = l = r = head

        while True:
            count = 0
            while r and count < k:   # use r to locate the range
                r = r.next
                count += 1
            if count == k:  # if size k satisfied, reverse the inner linked list
                pre, cur = r, l
                for _ in range(k):
                    cur.next, cur, pre = pre, cur.next, cur  # standard reversing
                jump.next, jump, l = pre, l, r  # connect two k-groups
            else:
                return dummy.next
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值