# -*- 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()

最新文章

  1. HDU 2295 Radar (重复覆盖)
  2. 成功转移安卓手机QQ聊天记录
  3. 每天一个linux命令---导出到文件
  4. tiny_cnn 阅读(1)
  5. 关于eclipse中MAVEN WEB工程中编译问题
  6. React入门--------JSX
  7. 学习Shell脚本编程(第2期)_编写修改权限及执行Shell程序的步骤
  8. ci 4.2
  9. Using GET_GROUP_SELECTION For Record Groups in Oracle Forms
  10. Java高级软件工程师面试考纲(转)
  11. 基于http协议的api接口对于客户端的身份认证方式以及安全措施
  12. Codeforces Round #200 (Div. 1) B. Alternating Current 栈
  13. Java SE (1)之 JFrame 组件 GridLayout布局
  14. PHP 日期格式化 参数参考
  15. 内外连接、组函数、DDL、DML和TCL
  16. 怎样下载并编译Android4.0内核源代码goldfish(图文)
  17. Hive中抽取连续多天登录用户
  18. 动态修改ViewPagerIndicator CustomTabPageIndicator Tab标签文字颜色
  19. VR开发相关资源
  20. 一次 Spark SQL 性能提升10倍的经历(转载)

热门文章

  1. MySQL(四)InnoDB中一棵B+树能存多少行数据
  2. c++ 在Ubuntu系统中使用access函数
  3. HDOJ-1100 Trees made to order
  4. k8s 启动pod的问题
  5. RAP2 前后端开发利器搭建
  6. Vue.js源码全方位深入解析--学习笔记
  7. PB自动换行
  8. docker registry-v2 搭建私有仓库
  9. SQL case when 遇到null值
  10. centos安装rocketMQ