Python实现双向链表

Python实现双向链表

双向链表是一种常见的线性数据结构,它允许在任意位置插入、删除、查找节点,具有很好的灵活性和效率。本篇文章将介绍Python如何实现双向链表,包括链表的节点定义、插入删除操作的实现、以及几个示例来说明如何使用双向链表。

链表节点定义

首先,我们需要定义一个双向链表的节点类。节点包含三个属性:前一个节点的指针prev、当前节点的值val、下一个节点的指针next。

class Node:
    def __init__(self, val=None, prev=None, next=None):
        self.val = val
        self.prev = prev
        self.next = next

双向链表的插入操作

在双向链表中,我们可以在指定位置插入一个新节点。插入节点的基本操作包括以下几步:

  1. 新建一个节点;
  2. 将前一个节点的next指向新节点;
  3. 将新节点的prev指向前一个节点,将新节点的next指向后一个节点;
  4. 将后一个节点的prev指向新节点。

具体实现如下:

class DoublyLinkedList:
    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.head = None
        self.tail = None
        self.size = 0

    def addAtIndex(self, index: int, val: int) -> None:
        if index < 0 or index > self.size:  # 处理非法索引
            return

        if index == 0:  # 在头部插入
            self.addAtHead(val)
        elif index == self.size:  # 在尾部插入
            self.addAtTail(val)
        else:
            node = Node(val)
            curr = self.head
            for i in range(index - 1):
                curr = curr.next
            node.prev = curr  # 1. 将前一个节点的next指向新节点
            node.next = curr.next  # 2. 将新节点的prev指向前一个节点,将新节点的next指向后一个节点
            curr.next.prev = node  # 3. 将后一个节点的prev指向新节点
            curr.next = node
            self.size += 1

双向链表的删除操作

在双向链表中,我们可以在指定位置删除一个节点。删除节点的基本操作包括以下几步:

  1. 将前一个节点的next指向后一个节点;
  2. 将后一个节点的prev指向前一个节点。

具体实现如下:

class DoublyLinkedList:
    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.head = None
        self.tail = None
        self.size = 0

    def deleteAtIndex(self, index: int) -> None:
        if index < 0 or index >= self.size:  # 处理非法索引
            return

        if index == 0:  # 删除头部节点
            self.head = self.head.next
            if self.head:  # 注意判断链表是否为空
                self.head.prev = None
            else:
                self.tail = None
        elif index == self.size - 1:  # 删除尾部节点
            self.tail = self.tail.prev
            self.tail.next = None
        else:
            curr = self.head
            for i in range(index):
                curr = curr.next
            curr.prev.next = curr.next  # 1. 将前一个节点的next指向后一个节点
            curr.next.prev = curr.prev  # 2. 将后一个节点的prev指向前一个节点
        self.size -= 1

示例说明

我们来看两个使用示例。

示例1:删除链表中的节点

dll = DoublyLinkedList()
dll.addAtHead(1)
dll.addAtTail(3)
dll.addAtIndex(1, 2)
dll.deleteAtIndex(1)
print(dll.head.val)  # 1
print(dll.head.next.val)  # 3

首先,创建一个双向链表,插入三个节点,值分别为1、2、3。然后,删除第二个节点,即值为2的节点。最后,打印链表头部节点和头部节点的下一个节点,结果分别为1、3。

示例2:反转双向链表

dll = DoublyLinkedList()
dll.addAtHead(1)
dll.addAtTail(3)
dll.addAtIndex(1, 2)

# 反转链表
new_head = dll.tail
while new_head:
    print(new_head.val)
    new_head = new_head.prev

首先,创建一个双向链表,插入三个节点,值分别为1、2、3。然后,使用while循环反转链表,按照逆序打印链表节点的值。最后的输出结果为3、2、1,说明链表已经被成功反转。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python实现双向链表 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 【C51】单片机定时器介绍

    C51单片机定时器介绍 C51单片机定时器是单片机中非常重要的一个模块,它可以用于实现定时、计数等功能。本文将详细讲解C51单片机定时器的作用、使用方法和示例。 作用 C51单片机定时器是单片机中用于实现定时、计数等功能的一个模块。它可以在一定的时间间隔内产生中断信号,从而实现定时、计数等功能。 使用方法 C51单片机定时器的使用方法如下: 设置定时器的工作…

    other 2023年5月5日
    00
  • C#实现Socket服务器及多客户端连接的方式

    C# 实现 Socket 服务器及多客户端连接的方式 在C#中,可以使用 Socket 类来实现网络编程。在这篇文章中,我将详细讲解如何使用C#实现Socket服务器及多客户端连接的方式。 什么是Socket? Socket是一种用于在两个应用程序之间进行通信的技术。它使用IP地址和端口号来定义一个连接,并通过TCP或UDP来传输数据。 实现Socket服务…

    other 2023年6月27日
    00
  • SpringBoot找不到映射文件的处理方式

    当开发SpringBoot应用过程中,我们可能会遇到以下错误提示:“Whitelabel Error Page:Not Found”或者“404 Not Found”。这一般是由于SpringBoot找不到映射文件所致。 针对这种情况,我们可以采取以下方式进行处理: 1. 检查Controller路径 通常情况下,SpringBoot的路径映射是通过@Con…

    other 2023年6月25日
    00
  • vivo X6怎么开启开发者模式?开发者模式开启方法

    下面我会详细讲解“vivo X6怎么开启开发者模式?开发者模式开启方法”的完整攻略,过程中会包含两条示例说明。 一、什么是“开发者模式” “开发者模式”是一个Android系统中的隐藏功能,用于给开发者提供更多的操作权限。通过开启“开发者模式”,用户可以在手机上进行更多的高级设置和调试控制,如USB调试、界面的布局绘制等。 二、如何开启“开发者模式” 以下是…

    other 2023年6月26日
    00
  • iOS10.3正式版升级需要多大空间 更新升级iOS10.3需要占用多大内存(附升级教程)

    iOS 10.3正式版升级攻略 升级所需空间 在升级iOS 10.3正式版之前,你需要确保你的设备有足够的可用空间来完成升级过程。根据我们的经验,iOS 10.3正式版的升级需要大约2GB的可用空间。 检查可用空间 在开始升级之前,你可以通过以下步骤检查你的设备上的可用空间: 打开设备的设置应用程序。 点击\”通用\”。 点击\”存储空间与iCloud使用情…

    other 2023年8月2日
    00
  • 苹果iOS刷机出现未知错误2005的解决方案大全

    苹果iOS刷机出现未知错误2005的解决方案大全 什么是“未知错误2005”? “未知错误2005”是指在刷写苹果手机 iOS 系统时出现的错误码,通常与硬件故障或无效 USB 端口等问题相关。该错误代码表明设备无法从 DFU 模式进入恢复模式。 解决方案 针对“未知错误2005”的问题,以下这些解决方案可能有所帮助: 检查电脑和 USB 端口 首先,用户需…

    other 2023年6月26日
    00
  • 怎样在cmd(命令提示符)下进行复制粘贴操作

    怎样在cmd(命令提示符)下进行复制粘贴操作 在Windows操作系统中,命令提示符(cmd)是一个非常实用的命令行工具,可以在其中运行各种命令。但是,如果你想要快速复制和粘贴多行文本到命令提示符窗口中,可能就会感到困难。在本文中,我们将介绍在命令提示符中进行复制和粘贴的几种方法。 方法一:使用鼠标右键 这是最简单的方法,只需使用鼠标右键点击命令提示符窗口的…

    其他 2023年3月28日
    00
  • JavaScript中数组去重常用的五种方法详解

    JavaScript中数组去重常用的五种方法详解 在JavaScript中数组去重是非常实用的技巧,可以帮助我们快速地去除数组中重复的元素,以减少数据的冗余和提高数据处理效率。接下来将详细介绍JavaScript数组去重的五种常用方法。 方法一:使用Set去重 使用Set可以轻松地实现数组去重,因为Set会自动去除重复的元素,而且Set可以很方便地转换为数组…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部