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日

相关文章

  • webpack vue项目开发环境局域网访问方法

    Webpack 配置的 Vue 项目开发环境默认只能在本机进行访问。如果要在局域网内访问,则需要进行相应的配置。下面详细讲解 webpack vue 项目开发环境局域网访问方法的完整攻略。 1. 修改webpack配置 首先,我们需要修改 webpack 的配置文件,将 Host 配置为 0.0.0.0,表示接受所有的网络访问请求。 在 webpack.de…

    other 2023年6月27日
    00
  • 解决ant design vue中树形控件defaultExpandAll设置无效的问题

    根据你的要求,我将为你讲解如何解决Ant Design Vue中树形控件defaultExpandAll设置无效的问题。 问题描述 在Ant Design Vue中,使用树形控件的时候,我们可以通过设置defaultExpandAll属性来实现默认展开所有节点。但有时候该属性设置无效,所有节点都没有默认展开。这是因为我们可能没有正确配置其他相关属性或者监听了…

    other 2023年6月27日
    00
  • Ruby基本的环境变量设置以及常用解释器命令介绍

    下面是Ruby基本的环境变量设置以及常用解释器命令介绍的攻略: Ruby环境变量设置 PATH环境变量 在安装Ruby之后,我们需要将其添加到系统的PATH环境变量中,这样我们就可以直接使用命令行来调用Ruby。在Windows系统下,可以按如下步骤进行设置: 打开“控制面板”,在搜索框中输入“环境变量”,选择“编辑系统环境变量”。 在“系统属性”窗口中选择…

    other 2023年6月27日
    00
  • WPS for Linux(ubuntu)字体配置(字体缺失解决办法)

    WPS for Linux(ubuntu)字体配置(字体缺失解决办法) WPS是一款跨平台的办公软件,支持Windows、Linux和macOS等操作系统。在Linux系统中,WPS for Linux(ubuntu)字体配置是一个常见的问题,因为WPS在Linux系统中需要依赖一些字体库,如果缺失这些字体库,就会导致WPS无法正常显示中文等内容。本文将介绍…

    other 2023年5月5日
    00
  • 青龙面板拉库解决没有或丢失依赖can‘t find module的保姆级教程(附青龙面板脚本仓库)

    下面就为大家详细讲解“青龙面板拉库解决没有或丢失依赖can‘t find module的保姆级教程”。 背景 在使用青龙面板进行任务管理时,由于依赖的缺失或者丢失,可能会出现can’t find module(无法找到模块)的情况。这时需要通过拉取库文件,解决缺失依赖的问题。 解决步骤 1. 进入青龙面板 首先,进入青龙面板,并进入终端界面。 2. 判断缺失…

    other 2023年6月26日
    00
  • Android仿今日头条滑动页面导航效果

    一、介绍 在Android开发中,实现滑动页面导航效果是比较常见的需求之一。本文针对如何实现仿今日头条的页面滑动导航效果进行详细讲解。 二、实现步骤 1.在布局文件中定义ViewPager和TabLayout控件,用于展示滑动页面和导航栏; 2.在Java代码中定义FragmentPagerAdapter,ViewPager的适配器;通过适配器承载Fragm…

    other 2023年6月20日
    00
  • jenkins部署分支报finished:unstable的问题解决

    当然,我可以为您提供有关“Jenkins部署分支报finished:unstable的问题解决”的完整攻略,以下是详细说明: 问题描述 在使用Jenkins分支部署时,可能会遇到“finished:unstable”状态的问题。这种情况通常表示构建过程中出现了一些问题,但构建仍然完成了。这可能会导致部署失败或出现其他问题。 问题解决 以下是解决Jenkins…

    other 2023年5月7日
    00
  • IDEA自定义常用代码块及自定义快捷摸板

    关于“IDEA自定义常用代码块及自定义快捷摸板”的攻略,可以分为以下几个步骤: 打开设置面板 在IDEA中,点击“File” -> “Settings” (或使用快捷键“Ctrl + Alt + S”),进入“Settings”面板。 选择“Editor” -> “Live Templates” 在左侧的菜单栏中,选择“Editor” ->…

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