Python数据结构之翻转链表

对于“Python数据结构之翻转链表”的完整攻略,我会按照以下顺序进行讲解:

1.什么是链表?

2.如何翻转链表?

3.示例1:翻转一个简单的链表

4.示例2:翻转一个带环的链表

5.如何在Python中实现翻转链表?

接下来,我会详细讲解每个部分。

什么是链表?

链表是一种数据结构,它由一系列的节点组成,每个节点包含了数据和指向下一个节点的指针。链表有很多种类型,包括单向链表、双向链表和循环链表等。链表相比于数组,有其自身的优势和劣势,我们可以在具体使用的时候选择不同的数据结构。

如何翻转链表?

翻转链表是指将链表中的节点按照相反的顺序重新排列,比如如果原先的链表是1-2-3-4-5,那么翻转后的链表就是5-4-3-2-1。

翻转链表的基本思路是遍历链表并将各个节点的指针反转。具体来说,我们可以设置三个指针prev,curr和next,初始化时,prev指向None,curr指向链表的头节点,next指向curr的下一个节点。然后,我们需要在循环中对curr节点的指针进行反转,即将该节点的next指针指向prev,同时更新prev、curr和next指针。最后,返回prev指针,即新链表的头节点。

示例1:翻转一个简单的链表

假设我们有一个简单的链表:1-2-3-4-5。我们可以使用如下代码翻转该链表:

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

def reverseList(head: ListNode) -> ListNode:
    prev = None
    curr = head
    while curr:
        next_node = curr.next
        curr.next = prev
        prev = curr
        curr = next_node
    return prev

# 创建链表
head = ListNode(1)
node1 = ListNode(2)
node2 = ListNode(3)
node3 = ListNode(4)
node4 = ListNode(5)
head.next = node1
node1.next = node2
node2.next = node3
node3.next = node4

# 输出原链表
curr = head
while curr:
    print(curr.val, end=" ")
    curr = curr.next
# 输出:1 2 3 4 5

# 翻转链表
new_head = reverseList(head)

# 输出新链表
curr = new_head
while curr:
    print(curr.val, end=" ")
    curr = curr.next
# 输出:5 4 3 2 1

示例2:翻转一个带环的链表

接下来,我们考虑一个较为复杂的情况,我们在链表中加入一个环,其中一部分节点形成环。比如链表是1-2-3-4-5,并且节点3和节点5形成了环路,即节点5的next指针指向节点3。

我们可以使用以下代码实现该功能:

# 创建带环的链表
head = ListNode(1)
node1 = ListNode(2)
node2 = ListNode(3)
node3 = ListNode(4)
node4 = ListNode(5)
head.next = node1
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node2  # 添加环

# 输出原链表
curr = head
for i in range(10):
    print(curr.val, end=" ")
    curr = curr.next
# 输出:1 2 3 4 5 3 4 5 3 4

# 翻转链表
new_head = reverseList(head)

# 输出新链表
curr = new_head
for i in range(10):
    print(curr.val, end=" ")
    curr = curr.next
# 输出:4 3 2 1 5 3 4 5 3 4

从上面的代码可以看出,翻转链表的函数能够正确处理带环的链表,而且在翻转后仍然能够保留原来的环路。

如何在Python中实现翻转链表?

现在,我们将翻转链表的代码封装到一个函数中。同时,我们也需要实现一个函数用来创建链表。具体如下:

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

def createList(vals: List[int]) -> ListNode:
    # 创建链表
    head = ListNode(vals[0])
    curr = head
    for val in vals[1:]:
        curr.next = ListNode(val)
        curr = curr.next
    return head

def reverseList(head: ListNode) -> ListNode:
    prev = None
    curr = head
    while curr:
        next_node = curr.next
        curr.next = prev
        prev = curr
        curr = next_node
    return prev

现在,我们就可以使用这些函数对任意的链表进行翻转了,比如:

# 创建链表
head = createList([1, 2, 3, 4, 5])

# 输出原链表
curr = head
while curr:
    print(curr.val, end=" ")
    curr = curr.next
# 输出:1 2 3 4 5

# 翻转链表
new_head = reverseList(head)

# 输出新链表
curr = new_head
while curr:
    print(curr.val, end=" ")
    curr = curr.next
# 输出:5 4 3 2 1

总之,翻转链表是一个常见的面试问题,掌握该问题的解决方法对于编程人员具有非常重要的意义。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python数据结构之翻转链表 - Python技术站

(1)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • 稀疏数组

    引入 当在网页上下棋类游戏时,玩到中途想要离开,但是我们需要保存进度,方便下次继续 我们应该怎么实现 ? 以围棋举例 使用二维数组将棋盘记下 ,如 0 为 没有棋子 ,1 为 黑子 , 2为白子 但是没有棋子的地方都为 0 ,整个二维数组充斥着大量的无效数据 0 我们需要想一个办法来 优化存储的方式 基本介绍 当一个数组中大部分元素是同一个值时,我们可以使用…

    算法与数据结构 2023年4月19日
    00
  • 带你了解Java数据结构和算法之队列

    带你了解Java数据结构和算法之队列 一、介绍 队列是已知的最古老和最常用的数据结构之一。它是一个线性结构,它遵循一个先进先出的原则,在日常生活中我们也很容易碰到队列。比如:在银行排队办理业务、队列中的电影厅、厨房中的菜单等等。 队列的操作主要有两种:入队(enqueue)和出队(dequeue)。插入操作只能在队尾进行,删除操作只能在队头进行。还有一些常用…

    数据结构 2023年5月17日
    00
  • 「学习笔记」AC 自动机

    「学习笔记」AC 自动机 点击查看目录 目录 「学习笔记」AC 自动机 算法 问题 思路 代码 例题 Keywords Search 玄武密码 单词 病毒 最短母串 文本生成器 背单词 密码 禁忌 前置:「学习笔记」字符串基础:Hash,KMP与Trie。 好像对例题的讲解越来越抽象了? 算法 问题 求 \(n\) 个单词在一个长度为 \(m\) 的文章里出…

    算法与数据结构 2023年5月5日
    00
  • AtCoder Beginner Contest 300

    A – N-choice question (abc300 a) 题目大意 给定一个元素互不相同的数组\(c\)和 \(a,b\),找到 \(i\)使得 \(c_i = a + b\) 解题思路 直接for循环寻找即可。 神奇的代码 #include <bits/stdc++.h> using namespace std; using LL = …

    算法与数据结构 2023年4月30日
    00
  • C语言深入浅出解析二叉树

    C语言深入浅出解析二叉树攻略 什么是二叉树 二叉树是一种树形数据结构,其每个节点最多只有两个子节点,分别称为其左子节点和右子节点。一般采用链式存储方式来实现二叉树,也可以使用数组来存储。 二叉树的遍历 二叉树的遍历分为三种方式:前序遍历,中序遍历和后序遍历。 前序遍历 前序遍历的顺序是先遍历根节点,然后遍历左子树,最后遍历右子树。可以使用递归或栈来实现。 v…

    数据结构 2023年5月17日
    00
  • Java链表数据结构及其简单使用方法解析

    Java链表数据结构及其简单使用方法解析 概述 链表是一种非线性结构,由一系列节点按照顺序连接而成。每个节点由数据域和指针域组成,数据域用于存储数据,指针域用于指向下一个节点或者上一个节点。在Java中,链表有多种实现方式,常见的有单向链表、双向链表等。 单向链表的实现 以下是一个单向链表的实现代码示例: public class Node { privat…

    数据结构 2023年5月17日
    00
  • C语言编程数据结构线性表之顺序表和链表原理分析

    C语言编程数据结构线性表之顺序表和链表原理分析 线性表的定义 线性表是由n(n>=0)个数据元素a1、a2、…、an组成的有限序列,通常用(a1, a2, …, an)表示,其中a1是线性表的第一个元素,an是线性表的最后一个元素。线性表中的元素个数n称为线性表的长度,当n=0时,线性表为空表。 线性表的分类 根据存储结构,线性表可以分为顺序表…

    数据结构 2023年5月17日
    00
  • C语言数据结构实例讲解单链表的实现

    C语言数据结构实例讲解单链表的实现 单链表是一种线性的数据结构,它由一系列节点组成,每个节点都包含一个数据域和一个指向下一个节点的指针域。单链表常用于需要频繁插入删除元素的场景中。 单链表的数据结构设计 在C语言中,我们可以使用结构体来定义单链表的节点: typedef struct node { int data; // 数据域 struct node* …

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部