python怎么实现redis双链表
redis 双链表
特点:
len: O(1),获取链表长度
head: O(1), 头部第一个节点
tail: O(1) 尾部第一个节点
无环: 非循环链表
void *: 存储任意类型数据。 (动态语言天然自带)
2.双链表API接口
创建/销毁/初始化:
listCreate
listEmpty
listRelease
添加节点/删除节点:
listAddNodeHead
listAddNodeTail
listInsertNode
listDelNode
实现迭代器/正向/反向遍历:
listGetIterator
listReleaseIterator
listRewind
listRewindTail
listNext
list复制,查找,旋转合并操作:listDup
listSearchKey
listIndex
listRotateTailToHead
listRotateHeadToTail
listJoin
源码
3.使用python实现redis双链表的api
参考redis list定义节点和DLinkList
python动态语言需要手动管理内存申请释放.
使用生成器, 偷懒式实现正向反向遍历.
""" 参考redis adlist.c. 实现双链表相关的api head tail None <- <- <- 1 2 3 -> -> -> None len:3 """ import copy from typing import Any class Node(object): def __init__(self, data) -> None: self.next = None self.pre = None self.data = data def __str__(self) -> str: return f"{self.data}" class DLinkList(object): def __init__(self) -> None: self.head = None self.tail = None self.len = 0 def empty(self) -> None: self.head = None self.tail = None self.len = 0 def add_node_head(self, data=None) -> Node: """[头插法] Args: data ([type], optional): [description]. Defaults to None. """ new_node = Node(data=data) if self.len == 0: # 链表为空. 处理头/尾指针 self.tail = new_node self.head = new_node else: # 插入新节点 new_node.next = self.head self.head.pre = new_node self.head = new_node self.len += 1 return new_node def add_node_tail(self, data: Any=None) -> Node: """[尾插法] Args: data ([type], optional): [description]. Defaults to None. """ new_node = Node(data=data) if self.len == 0: # 链表为空. 处理头/尾指针 self.tail = new_node self.head = new_node else: # 插入新节点 new_node.pre = self.tail new_node.next = self.tail.next self.tail.next = new_node # 更新尾指针 self.tail = new_node self.len += 1 return new_node def insert_node(self, old_node: Node=None, data: Any=None, after: bool=False) -> None: """[插入新节点, 在旧节点的前/后] Args: old_node (Node, optional): [旧节点]. Defaults to None. data (Any, optional): [新数据]. Defaults to None. after (Bool, optional): [是否在之后插入]. Defaults to False. """ assert self.len, f"self.len({self.len}) must > 0" new_node = Node(data=data) if after: new_node.pre = old_node new_node.next = old_node.next old_node.next.pre = new_node old_node.next = new_node if self.tail == old_node: self.tail = new_node else: new_node.pre = old_node.pre new_node.next = old_node old_node.pre.next = new_node old_node.pre = new_node if self.head == old_node: self.head = new_node self.len += 1 def del_node(self, node: Node) -> None: """[删除节点] Args: node (Node): [description] """ assert self.len, "DLinklist is None" if not node: return if node == self.head: self.head = node.next else: # 1.处理next node.pre.next = node.next if node == self.tail: self.tail = node.pre else: # 2.处理pre node.next.pre = node.pre node.pre = None node.next = None del node self.len -= 1 def next(self, reversed:bool=False): """[获取生成器] Args: reversed (bool, optional): [description]. Defaults to False. Returns: [type]: [description] """ if reversed: return self._reverse_next() return self._next() def _reverse_next(self): """[反向迭代, 使用生成器记录状态] Yields: [type]: [description] """ cur = self.tail idx = self.len - 1 while cur: yield (idx, cur) idx -= 1 cur = cur.pre def _next(self): """[正向迭代, 使用生成器记录状态]] Yields: [type]: [description] """ cur = self.head idx = 0 while cur: yield (idx, cur) idx += 1 cur = cur.next def dup(self): return copy.deepcopy(self) def find(self, key: Any=None) -> tuple: if not key: return g = self.next() for idx, node in g: if node.data == key: return idx, node return -1, None def rotate_tail_to_head(self) -> None: """[正向旋转节点] 移动尾节点,插入到头部 """ assert self.len >= 2, "dlist len must >=2" head = self.head tail = self.tail # remove tail self.tail = tail.pre self.tail.next = None # move to head tail.next = head tail.pre = head.pre self.head = tail def rotate_head_to_tail(self) -> None: """[反向旋转节点] 移动头点,插入到尾部 """ assert self.len >= 2, "dlist len must >=2" head = self.head tail = self.tail # remove head self.head = head.next self.head.pre = None # move to tail tail.next = head head.pre = tail self.tail = head self.tail.next = None def join(self, dlist: Any=None): """[合并双链表] Args: dlist (Any, optional): [description]. Defaults to None. """ pass def __str__(self) -> str: ans = "" for idx, node in self.next(reversed=False): ans += f"idx:({idx}) data:({node.data})n" return ans def test_add_node(dlist:DLinkList=None): n = 5 for i in range(n): dlist.add_node_tail(data=i) # dlist.add_node_head(data=i) print(dlist) def test_del_node(dlist:DLinkList=None): i = dlist.len while i: node = None dlist.del_node(node) i -= 1 print(dlist) def test_insert_node(dlist:DLinkList=None): # dlist.insert_node(old_node=old_node, data=100, after=True) # print(dlist, id(dlist)) # nlist = dlist.dup() # print(nlist, id(nlist)) idx, fnode = dlist.find(1) print('find node:', idx, fnode) dlist.insert_node(fnode, 100, after=True) print("insert after") print(dlist) dlist.insert_node(fnode, 200, after=False) print("insert before") print(dlist) def test_rotate(dlist:DLinkList=None): print("move head to tail") dlist.rotate_head_to_tail() print(dlist) print("move tail to head") dlist.rotate_tail_to_head() print(dlist) def test_join(dlist:DLinkList=None, olist:DLinkList=None): print("join list") nlist = dlist.join(olist) print(nlist) def main(): dlist = DLinkList() test_add_node(dlist) # test_del_node(dlist) # test_insert_node(dlist) test_rotate(dlist) if __name__ == "__main__": main()
以上是python怎么实现redis双链表的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

PHP和Python各有优劣,选择取决于项目需求和个人偏好。1.PHP适合快速开发和维护大型Web应用。2.Python在数据科学和机器学习领域占据主导地位。

Docker利用Linux内核特性,提供高效、隔离的应用运行环境。其工作原理如下:1. 镜像作为只读模板,包含运行应用所需的一切;2. 联合文件系统(UnionFS)层叠多个文件系统,只存储差异部分,节省空间并加快速度;3. 守护进程管理镜像和容器,客户端用于交互;4. Namespaces和cgroups实现容器隔离和资源限制;5. 多种网络模式支持容器互联。理解这些核心概念,才能更好地利用Docker。

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

Redis的数据库方法包括内存数据库和键值存储。1)Redis将数据存储在内存中,读写速度快。2)它使用键值对存储数据,支持复杂数据结构,如列表、集合、哈希表和有序集合,适用于缓存和NoSQL数据库。

CentOS 安装 Nginx 需要遵循以下步骤:安装依赖包,如开发工具、pcre-devel 和 openssl-devel。下载 Nginx 源码包,解压后编译安装,并指定安装路径为 /usr/local/nginx。创建 Nginx 用户和用户组,并设置权限。修改配置文件 nginx.conf,配置监听端口和域名/IP 地址。启动 Nginx 服务。需要注意常见的错误,如依赖问题、端口冲突和配置文件错误。性能优化需要根据具体情况调整,如开启缓存和调整 worker 进程数量。

在 VS Code 中,可以通过以下步骤在终端运行程序:准备代码和打开集成终端确保代码目录与终端工作目录一致根据编程语言选择运行命令(如 Python 的 python your_file_name.py)检查是否成功运行并解决错误利用调试器提升调试效率

Python在自动化、脚本编写和任务管理中表现出色。1)自动化:通过标准库如os、shutil实现文件备份。2)脚本编写:使用psutil库监控系统资源。3)任务管理:利用schedule库调度任务。Python的易用性和丰富库支持使其在这些领域中成为首选工具。

从 Redis 官方源下载源码包编译安装,保证最新稳定版本,可个性化定制。具体步骤如下:更新软件包列表创建 Redis 目录下载 Redis 源码包解压源码包编译安装配置并修改 Redis 配置启动 Redis检查启动状态
