【Python数据结构】反转链表的方法

反转链表是指改变单链表中节点之间的连接关系,使得原本的正向顺序变为反向顺序。以下是反转单链表的常见方法:

一. 迭代法

迭代法反转链表的流程:使用三个指针,通常命名为 prev、current 和 next:

  1. 初始化 prev 指针为空,current 指针指向头节点;
  2. 遍历链表,每次迭代过程中:
    • 将 current 节点的下一个节点暂存到 next 指针;
    • 修改 current 节点的 next 指针使其指向 prev 节点;
    • prev 和 current 指针都向前移动一步,即将 current 更新为原来的 next,prev 更新为 current;
  3. 迭代结束后,prev 指针将指向新的头节点。

下面是具体的代码实现:

# 定义链表节点类
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def reverseList_iteratively(head):
    """
    迭代法反转链表
    :param head: ListNode,链表的头节点
    :return: ListNode,反转后的链表头节点
    """
    # 初始化前驱节点为None
    prev = None
    # 当前节点开始为头节点
    current = head
    
    # 只要当前节点不为空
    while current is not None:
        # 保存当前节点的下一个节点
        next_node = current.next
        
        # 将当前节点的next指针指向其前驱节点
        current.next = prev
        
        # 更新前驱节点和当前节点,准备处理下一个节点
        prev = current
        current = next_node
        
    # 循环结束后,prev将是反转后的新头节点
    return prev

# 创建链表示例
head = ListNode(1)
head.next = ListNode(2)
head.next.next = ListNode(3)
head.next.next.next = ListNode(4)
head.next.next.next.next = ListNode(5)

# 反转链表
reversed_head = reverseList_iteratively(head)

二. 递归法

  • 设定递归函数,传入当前节点作为参数:
    • 当前节点为空或只有一个节点时,直接返回该节点(此时无需反转);
    • 否则,递归调用函数处理下一个节点,得到反转后的下一个节点;
    • 然后修改当前节点的 next 指针,使之指向反转后返回的节点;
    • 最后返回当前节点作为新的子链表的头节点。

请注意,在递归版本中,由于递归调用机制,函数会自动回溯并逐步恢复链表节点的next指针指向,最后返回反转后的头节点。迭代法则是通过循环来逐步更改每个节点的next指针,直到整个链表反转完成。

下面是具体的代码实现:

def reverseList_recursively(head):
    """
    递归法反转链表
    :param head: ListNode,链表的头节点
    :return: ListNode,反转后的链表头节点
    """
    # 递归终止条件:空节点或者只有一个节点的情况,直接返回该节点
    if not head or not head.next:
        return head

    # 递归调用,反转后续链表
    new_head = reverseList_recursively(head.next)

    # 逆转当前节点的next指针,使它指向其前一个节点
    head.next.next = head

    # 断开当前节点与之前序列的连接
    head.next = None

    # 返回新链表的头节点
    return new_head

三. 头插法(创建新链表)

  1. 创建一个新的空节点作为新链表的头节点;
  2. 遍历原链表,对于每个节点,将其从原链表摘下并插入到新链表的头部(利用链表的头插法特性);
  3. 完成遍历后,新链表的头节点即为原链表的最后一个节点,也就是反转后的头节点。

这种方式虽然可以实现反转,但并不是严格意义上的原地反转,因为它创建了新的链表结构。

下面是具体的代码实现:

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def reverseList_headInsertion(head):
    # 创建一个虚拟头节点
    dummy = ListNode(0)
    # 新链表的当前节点始终是dummy节点
    curr = dummy

    # 遍历原链表
    while head:
        # 保存当前节点的下一个节点
        next_node = head.next

        # 将当前节点插入到新链表的头部
        head.next = curr.next
        curr.next = head

        # 移动到原链表的下一个节点
        head = next_node

    # 返回新链表的实际头节点(即原链表的尾节点)
    return dummy.next

四. 原地反转法

  • 不创建新链表,直接在原链表上修改节点间的指向关系。
    • 这实际上就是迭代法的一种特殊情况,只是不额外使用 prev 指针,而是直接更新节点间的 next 指针。

下面是具体的代码实现:

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

def reverseList(head):
    prev = None
    current = head
    while current is not None:
        next_temp = current.next  # 保存当前节点的下一个节点
        current.next = prev  # 将当前节点的next指针指向前一个节点
        prev = current  # 更新前一个节点为当前节点
        current = next_temp  # 移动到下一个节点
    return prev  # 返回新的头节点

# 示例使用:
# 创建一个链表: 1 -> 2 -> 3 -> 4 -> 5
head = ListNode(1)
head.next = ListNode(2)
head.next.next = ListNode(3)
head.next.next.next = ListNode(4)
head.next.next.next.next = ListNode(5)

# 反转链表
new_head = reverseList(head)

# 遍历查看反转后的链表: 5 -> 4 -> 3 -> 2 -> 1
while new_head is not None:
    print(new_head.val)
    new_head = new_head.next

这段代码首先定义了一个ListNode类来表示链表节点,然后实现了reverseList函数用于原地反转链表。在反转过程中,我们只修改了链表中节点的next指针,没有创建任何新的节点,所以这种方法的空间复杂度是O(1)。

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Python数据结构课程设计,我可以给你一些建议。首先,你可以选择一个或多个常见的数据结构,如列表、字典、集合、堆栈、队列和树等,然后设计一些与这些数据结构相关的实际问题。 以下是一个示例课程设计的提纲: 1. 引言和背景知识 - 介绍数据结构的概念和重要性 - 讨论Python中内置的一些常见数据结构 2. 列表操作 - 列表的创建和初始化 - 列表的索引和切片操作 - 列表元素的增删改查 - 列表的排序和反转 3. 字典操作 - 字典的创建和初始化 - 字典元素的增删改查 - 字典的遍历和排序 4. 集合操作 - 集合的创建和初始化 - 集合元素的增删查找 - 集合的交集、并集和差集运算 5. 堆栈和队列 - 堆栈的实现和操作(使用列表或链表) - 队列的实现和操作(使用列表或链表) - 应用案例:括号匹配问题、迷宫求解等 6. 树的基本操作 - 树的创建和遍历(前序、中序、后序) - 树的搜索和插入操作 - 二叉搜索树的实现和应用 7. 课程设计项目 - 学生根据所学的数据结构知识,设计和实现一个具体的项目 - 可以是一个小型的应用程序或算法,如电话簿管理系统、图书馆管理系统等 8. 总结和展望 - 总结所学的数据结构知识和编程技巧 - 探讨数据结构在实际开发中的应用 - 展望未来学习和深入研究的方向 以上只是一个简要的提纲,你可以根据自己的实际情况和课程要求进行调整和扩展。希望对你有所帮助!如果有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值