python实现双链表

实现双链表需要明确双链表的特点:每个节点都有两个指针,一个指向前一个节点,一个指向后一个节点。双链表的操作包括插入、删除、查找等。接下来,我将详细讲解如何在Python中实现双链表。

1. 定义节点类

class Node:
    def __init__(self, data):
        self.data = data  # 数据
        self.prev = None  # 前一个节点的指针
        self.next = None  # 后一个节点的指针

在这段代码中,我们定义了一个节点类,这个类包含三个成员变量。其中,data代表节点中存储的数据,prev代表前一个节点的指针,next代表后一个节点的指针。

2. 定义双链表类

class DoubleLinkedList:
    def __init__(self):
        self.head = None  # 头节点
        self.tail = None  # 尾节点
        self.length = 0   # 链表长度

    # 插入节点
    def insert(self, data):
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
            self.tail = new_node
        else:
            new_node.prev = self.tail  # 新节点的prev指向尾节点
            self.tail.next = new_node  # 尾节点的next指向新节点
            self.tail = new_node       # 更新尾节点
        self.length += 1

    # 删除节点
    def delete(self, data):
        current = self.head
        while current is not None:
            if current.data == data:
                if current == self.head:
                    self.head = current.next
                    if self.head is not None:
                        self.head.prev = None
                    else:
                        self.tail = None
                elif current == self.tail:
                    self.tail = current.prev
                    self.tail.next = None
                else:
                    current.prev.next = current.next
                    current.next.prev = current.prev
                self.length -= 1
                return
            current = current.next

    # 遍历节点
    def traverse(self):
        current = self.head
        while current is not None:
            print(current.data)
            current = current.next

在这段代码中,我们定义了一个双链表类,这个类包含三个成员变量:head代表头节点、tail代表尾节点、length代表链表长度。这个类还包含了三个方法:

  • insert(data):插入节点
  • delete(data):删除节点
  • traverse():遍历节点

3. 示例说明

示例1:用双链表实现数字加1

假设现在有一个整数链表,链表每个节点存储一位数字,头节点代表数字的最高位,尾节点代表数字的最低位。现在需要用双链表实现这个数字加1的功能。例如,输入链表1->2->3->4,输出链表1->2->3->5。代码如下:

class Solution:
    def plusOne(self, head: ListNode) -> ListNode:
        current = head
        carry = 1
        while current is not None:
            current.val += carry
            if current.val > 9:
                current.val = 0
            else:
                carry = 0
                break
            current = current.next
        if carry == 1:
            new_node = ListNode(1)
            new_node.next = head
            head = new_node
        return head

在这个示例中,我们定义了一个Solution类,这个类包含了一个plusOne()方法,用于实现数字加1的功能。在plusOne()方法中,我们首先遍历整个链表,对每个节点进行加1操作,当节点的值大于9时,将该节点的值设为0,并将carry置为1。当遍历完整个链表后,如果carry仍为1,说明需要在链表头插入一个值为1的节点。最后返回链表头。

示例2:用双链表实现LRU缓存

LRU缓存是一种常用的缓存算法,它的原理是将最近没有使用的缓存淘汰掉。我们可以用双链表实现LRU缓存的功能。例如,输入一组缓存数据,大小为3,访问顺序为1->2->3->4->1->2->5,输出淘汰掉的缓存和最终缓存的顺序。代码如下:

class LRUCache:
    def __init__(self, capacity: int):
        self.capacity = capacity  # 缓存容量
        self.cache = DoubleLinkedList()  # 双链表存储缓存
        self.keys = {}  # 哈希表存储键值对

    def get(self, key: int) -> int:
        if key in self.keys:
            self.cache.delete(key)
            self.cache.insert(key)
            return self.keys[key]
        else:
            return -1

    def put(self, key: int, value: int) -> None:
        if key in self.keys:
            self.cache.delete(key)
            self.cache.insert(key)
            self.keys[key] = value
        else:
            if self.cache.length == self.capacity:
                remove_key = self.cache.head.data
                self.cache.delete(remove_key)
                del self.keys[remove_key]
            self.cache.insert(key)
            self.keys[key] = value

    def traverse(self):
        self.cache.traverse()

# 示例
cache = LRUCache(3)
cache.put(1, 'A')
cache.put(2, 'B')
cache.put(3, 'C')
cache.put(4, 'D')
cache.put(1, 'A')
cache.put(2, 'B')
cache.put(5, 'E')
cache.traverse()

在这个示例中,我们定义了一个LRUCache类,这个类包含了三个方法:

  • get(key):获得键值对
  • put(key, value):存储键值对
  • traverse():遍历链表(测试用)

在put()方法中,我们首先判断输入的key是否已经存在于哈希表中。如果存在,我们就将这个key对应的节点移动到链表尾部,并更新哈希表中的值。如果不存在,我们就在链表尾部插入新节点,同时在哈希表中新建一个键值对。另外,如果缓存已经满了,我们就淘汰链表头部的节点。在get()方法中,我们只需要判断输入的key是否存在于哈希表中即可。

在这个示例中,我们用LRUCache类(缓存大小为3)存储了一组键值对(1->A、2->B、3->C、4->D、1->A、2->B、5->E)。我们将缓存的遍历结果输出,即可看到最终缓存的顺序。注意,在这个示例中,对于哪些需要删除的缓存数据,被淘汰的缓存顺序输出为:4->1->2。

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

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

相关文章

  • Vue图片放大镜组件的封装使用详解

    Vue图片放大镜组件的封装使用详解 1. 组件功能 该组件是一个基于Vue框架封装的图片放大镜组件。当用户鼠标移动到图片上时,鼠标正中心出现一个放大镜图层,能够实现对图片的放大查看。该组件主要由两部分组成:鼠标跟随图层、放大镜图层。 2. 组件使用 该组件的使用非常简单,以下是使用步骤: 2.1 引入组件 import Vue from ‘vue’ impo…

    other 2023年6月25日
    00
  • Eclipse导入SVN项目的三种方式

    Eclipse导入SVN项目的三种方式 如果你需要在Eclipse中管理和修改SVN项目,导入SVN项目是非常必要的。在本文中,我们将介绍Eclipse导入SVN项目的三种方式。 1. 使用Eclipse自带的SVN插件 第一种方式是使用Eclipse自带的SVN插件,该插件允许你直接从SVN服务器导入项目。下面是具体步骤: 在Eclipse中打开“SVN …

    其他 2023年3月28日
    00
  • 批处理BAT脚本中set命令的使用详解(批处理之家Batcher)

    批处理BAT脚本中set命令的使用详解 在批处理BAT脚本中,set命令是一个非常有用的命令,用于设置和显示环境变量。它可以用于存储和检索各种类型的数据,包括字符串、数字和文件路径等。本攻略将详细介绍set命令的使用方法和示例。 设置环境变量 set命令可以用于设置环境变量,语法如下: set 变量名=值 其中,变量名是要设置的环境变量的名称,值是要为该环境…

    other 2023年8月15日
    00
  • 王国风云3无法找到配置文件怎么办 王国风云3无法找到配置文件解决方法

    王国风云3无法找到配置文件怎么办 问题描述 在运行王国风云3游戏时,出现了无法找到游戏配置文件的错误,导致游戏无法启动。 解决方法 确认游戏安装目录下是否存在游戏配置文件。游戏配置文件通常是一个后缀名为“.ini”或“.cfg”的文件,它包含了游戏的配置信息。如果游戏配置文件确实不存在,可以从互联网上下载一份并手动放到游戏安装目录下。 如果游戏配置文件存在,…

    other 2023年6月25日
    00
  • Python数据类型学习笔记

    下面我来详细讲解如何学习Python数据类型以及如何使用Python进行数据类型的操作。本攻略适用于Python初学者。 1. 学习Python基本数据类型 Python中有五种基本数据类型,分别为数字类型、字符串类型、列表类型、元组类型和字典类型。在学习Python数据类型之前,首先需要了解Python的变量赋值机制和基本数据类型的概念。下面是相关内容的讲…

    other 2023年6月27日
    00
  • SQL实现递归及存储过程中In()参数传递解决方案详解

    下面我将为你详细讲解“SQL实现递归及存储过程中In()参数传递解决方案详解”的完整攻略。 SQL实现递归 什么是递归 递归(Recursion)指的是在函数内部调用函数本身的方法。在SQL中,递归主要使用WITH RECURSIVE语句来实现。 WITH RECURSIVE语句 WITH RECURSIVE语句是递归查询的核心语句,它的语法如下: WITH…

    other 2023年6月27日
    00
  • camunda工作流引擎简单入门

    Camunda工作流引擎简单入门 Camunda是一个开源的工作流引擎,能够帮助用户轻松地设计、自动化和优化业务流程。在本文中,我们将介绍一些基本的概念和步骤,以帮助您快速入门Camunda工作流引擎。 安装和启动Camunda 首先,你需要下载和安装Camunda。可以通过官方网站https://camunda.com/download/下载和安装。安装完…

    其他 2023年3月28日
    00
  • Android自定义popupwindow实例代码

    下面我会详细讲解“Android自定义popupwindow实例代码”的完整攻略。 什么是PopupWindow PopupWindow 是 Android 提供的一个弹出窗口组件,可以在当前窗口的上面弹出一个浮层。通常情况下,这个浮层会包含一些用户界面上的交互组件,例如列表、按钮等。 创建 PopupWindow 要创建 PopupWindow,你需要实例…

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