循环双端链表(python)
# -*- coding: utf-8 -*- class Node(object):
__slots__ = ('value', 'prev', 'next') # save memory def __init__(self, value=None, prev=None, next=None):
self.value, self.prev, self.next = value, prev, next class CircularDoubleLinkedList(object):
"""循环双端链表 ADT
多了个循环其实就是把 root 的 prev 指向 tail 节点,串起来
""" def __init__(self, maxsize=None):
self.maxsize = maxsize
node = Node()
node.next, node.prev = node, node
self.root = node
self.length = 0 def __len__(self):
return self.length def headnode(self):
return self.root.next def tailnode(self):
return self.root.prev def append(self, value): # O(1), 你发现一般不用 for 循环的就是 O(1),有限个步骤
if self.maxsize is not None and len(self) >= self.maxsize:
raise Exception('LinkedList is Full')
node = Node(value=value)
tailnode = self.tailnode() or self.root tailnode.next = node
node.prev = tailnode
node.next = self.root
self.root.prev = node
self.length += 1 def appendleft(self, value):
if self.maxsize is not None and len(self) >= self.maxsize:
raise Exception('LinkedList is Full')
node = Node(value=value)
if self.root.next is self.root: # empty
node.next = self.root
node.prev = self.root
self.root.next = node
self.root.prev = node
else:
node.prev = self.root
headnode = self.root.next
node.next = headnode
headnode.prev = node
self.root.next = node
self.length += 1 def remove(self, node): # O(1),传入node 而不是 value 我们就能实现 O(1) 删除
"""remove
:param node # 在 lru_cache 里实际上根据key 保存了整个node:
"""
if node is self.root:
return
else: #
node.prev.next = node.next
node.next.prev = node.prev
self.length -= 1
return node def iter_node(self):
if self.root.next is self.root:
return
curnode = self.root.next
while curnode.next is not self.root:
yield curnode
curnode = curnode.next
yield curnode def __iter__(self):
for node in self.iter_node():
yield node.value def iter_node_reverse(self):
"""相比单链表独有的反序遍历"""
if self.root.prev is self.root:
return
curnode = self.root.prev
while curnode.prev is not self.root:
yield curnode
curnode = curnode.prev
yield curnode def test_double_link_list():
dll = CircularDoubleLinkedList()
assert len(dll) == 0 dll.append(0)
dll.append(1)
dll.append(2) assert list(dll) == [0, 1, 2] assert [node.value for node in dll.iter_node()] == [0, 1, 2]
assert [node.value for node in dll.iter_node_reverse()] == [2, 1, 0] headnode = dll.headnode()
assert headnode.value == 0
dll.remove(headnode)
assert len(dll) == 2
assert [node.value for node in dll.iter_node()] == [1, 2] dll.appendleft(0)
assert [node.value for node in dll.iter_node()] == [0, 1, 2] if __name__ == '__main__':
test_double_link_list()
循环双端链表(python)的更多相关文章
- JAVA基础——链表结构之双端链表
双端链表:双端链表与传统链表非常相似.只是新增了一个属性-即对最后一个链结点的引用 如上图所示:由于有着对最后一个链结点的直接引用.所以双端链表比传统链表在某些方面要方便.比如在尾部插入一个链结点.双 ...
- Java数据结构——用双端链表实现队列
//================================================= // File Name : LinkQueue_demo //---------------- ...
- Java单链表、双端链表、有序链表实现
单链表: insertFirst:在表头插入一个新的链接点,时间复杂度为O(1) deleteFirst:删除表头的链接点,时间复杂度为O(1) 有了这两个方法,就可以用单链表来实现一个栈了,见htt ...
- 《Java数据结构与算法》笔记-CH5-链表-3双端链表
/** * 双端链表的实现 */ class LinkA { public long dData; public LinkA next; public LinkA(long d) { dData = ...
- java实现双端链表
PS:双端链表(持有对最后一个节点的引用,允许表尾操作与表头操作等效的功能) public class DoubleLinkedList { //节点类 static class Node { pub ...
- 队列(存储结构双端链表)--Java实现
/*用链表实现的队列--使用的是双端链表 *注意:空指针错误肯定是引用没有指向对象 * */ public class MyLinkedQueue { private MyFirstAndLastLi ...
- 双端链表--Java实现
/*双端链表--比普通链表多了一个指向最后一个节点的引用 * 特点: 链表可以进行尾巴插入--输出顺序和输入顺序一致 * 但是不可以进行尾巴删除因为没有倒数第二节点的引用 * */ public cl ...
- java数据结构——单链表、双端链表、双向链表(Linked List)
1.继续学习单链表,终于摆脱数组的魔爪了,单链表分为数据域(前突)和引用域(指针域)(后继),还有一个头结点(就好比一辆火车,我们只关心火车头,不关心其它车厢,只需知晓车头顺藤摸瓜即可),头结点没有前 ...
- Java实现 LeetCode 641 设计循环双端队列(暴力)
641. 设计循环双端队列 设计实现双端队列. 你的实现需要支持以下操作: MyCircularDeque(k):构造函数,双端队列的大小为k. insertFront():将一个元素添加到双端队列头 ...
随机推荐
- Lua 学习笔记 (1)
最简单的 lua脚本 , do print ("line:", indx) end 也可以写成 , do print("line:", indx) end lu ...
- 【面试题】如何删除 ArrayList 中奇数位置的元素?
如何删除 ArrayList 中奇数位置的元素? 面试题携程 import java.util.ArrayList; import java.util.Iterator; import java.ut ...
- WUSTOJ 1298: 操作格子(Java)
题目链接:
- 如何在mongoengine中使用referencefield引用本类
引用:原文 from mongoengine import * class Employee(Document): name = StringField() boss = ReferenceField ...
- Android--圆角背景style
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http: ...
- Linux安装JDK,Tomcat,Mysql+部署项目
安装VMWare虚拟机 下载地址(http://www.onlinedown.net/soft/2062.htm) 安装步骤很简单(除了选择安装路径),傻瓜式安装 同意协议 选择安装路径 安装 完成 ...
- Quartz入门以及相关表达式使用
目的: 1.Quartz简介及应用场景 2.Quartz简单触发器 SimpleTrigger介绍 3.Quartz表达式触发器CronTirgger介绍 4.Quartz中参数传递 5.Spring ...
- 手动编译ts的经过
动机 以前写ts或者es6,都是用在脚手架搭建的项目中,比如vue和react,当时当我识图写一个ts的demo的,我还要创建一个完整的vue或者react项目?明显不合适,那就要研究一下如何手动搭建 ...
- Linux上安装pstree命令(-bash: pstree: command not found)
一.pstree命令的安装 1.在 Mac OS上 brew install pstree 2.在 Fedora/Red Hat/CentOS yum -y install psmisc 3.在 Ub ...
- DG环境恢复同步遇到报错ORA-00353ORA-00334以及ORA-00600[2619], [47745]
问题说明 客户环境主库4节点RAC11.2.0.4,单实例DG环境,DG由于空间不足,导致同步中断,由于DG备库未应用的归档主库都再,本次恢复的方式,是开启dg mrp进程,自动同步追上主库. 以下遇 ...