单链表(python)
# -*- coding: utf-8 -*- class Node(object):
def __init__(self, value=None, next=None): # 这里我们 root 节点默认都是 None,所以都给了默认值
self.value = value
self.next = next def __str__(self):
"""方便你打出来调试,复杂的代码可能需要断点调试"""
return '<Node: value: {}, next={}>'.format(self.value, self.next) __repr__ = __str__ class LinkedList(object):
""" 链接表 ADT
[root] -> [node0] -> [node1] -> [node2]
""" def __init__(self, maxsize=None):
"""
:param maxsize: int or None, 如果是 None,无限扩充
"""
self.maxsize = maxsize
self.root = Node() # 默认 root 节点指向 None
self.tailnode = None
self.length = 0 def __len__(self):
return self.length def append(self, value): # O(1)
if self.maxsize is not None and len(self) >= self.maxsize:
raise Exception('LinkedList is Full')
node = Node(value) # 构造节点
tailnode = self.tailnode
if tailnode is None: # 还没有 append 过,length = 0, 追加到 root 后
self.root.next = node
else: # 否则追加到最后一个节点的后边,并更新最后一个节点是 append 的节点
tailnode.next = node
self.tailnode = 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)
if self.tailnode is None: # 如果原链表为空,插入第一个元素需要设置 tailnode
self.tailnode = node headnode = self.root.next
self.root.next = node
node.next = headnode
self.length += 1 def __iter__(self):
for node in self.iter_node():
yield node.value def iter_node(self):
"""遍历 从 head 节点到 tail 节点"""
curnode = self.root.next
while curnode is not self.tailnode: # 从第一个节点开始遍历
yield curnode
curnode = curnode.next # 移动到下一个节点
if curnode is not None:
yield curnode def remove(self, value): # O(n)
""" 删除包含值的一个节点,将其前一个节点的 next 指向被查询节点的下一个即可 :param value:
"""
prevnode = self.root #
for curnode in self.iter_node():
if curnode.value == value:
prevnode.next = curnode.next
if curnode is self.tailnode: # NOTE: 注意更新 tailnode
self.tailnode = prevnode
del curnode
self.length -= 1
return 1 # 表明删除成功
else:
prevnode = curnode
return -1 # 表明删除失败 def find(self, value): # O(n)
""" 查找一个节点,返回序号,从 0 开始 :param value:
"""
index = 0
for node in self.iter_node(): # 我们定义了 __iter__,这里就可以用 for 遍历它了
if node.value == value:
return index
index += 1
return -1 # 没找到 def popleft(self): # O(1)
""" 删除第一个链表节点
"""
if self.root.next is None:
raise Exception('pop from empty LinkedList')
headnode = self.root.next
self.root.next = headnode.next
self.length -= 1
value = headnode.value if self.tailnode is headnode: # 勘误:增加单节点删除 tailnode 处理
self.tailnode = None
del headnode
return value def clear(self):
for node in self.iter_node():
del node
self.root.next = None
self.length = 0
self.tailnode = None def reverse(self):
"""反转链表"""
curnode = self.root.next
self.tailnode = curnode # 记得更新 tailnode,多了这个属性处理起来经常忘记
prevnode = None while curnode:
nextnode = curnode.next
curnode.next = prevnode if nextnode is None:
self.root.next = curnode prevnode = curnode
curnode = nextnode def test_linked_list():
ll = LinkedList() ll.append(0)
ll.append(1)
ll.append(2)
ll.append(3) assert len(ll) == 4
assert ll.find(2) == 2
assert ll.find(-1) == -1 assert ll.remove(0) == 1
assert ll.remove(10) == -1
assert ll.remove(2) == 1
assert len(ll) == 2
assert list(ll) == [1, 3]
assert ll.find(0) == -1 ll.appendleft(0)
assert list(ll) == [0, 1, 3]
assert len(ll) == 3 headvalue = ll.popleft()
assert headvalue == 0
assert len(ll) == 2
assert list(ll) == [1, 3] assert ll.popleft() == 1
assert list(ll) == [3]
ll.popleft()
assert len(ll) == 0
assert ll.tailnode is None ll.clear()
assert len(ll) == 0
assert list(ll) == [] def test_linked_list_remove():
ll = LinkedList()
ll.append(3)
ll.append(4)
ll.append(5)
ll.append(6)
ll.append(7)
ll.remove(7)
print(list(ll)) def test_linked_list_reverse():
ll = LinkedList()
n = 10
for i in range(n):
ll.append(i)
ll.reverse()
assert list(ll) == list(reversed(range(n))) def test_linked_list_append():
ll = LinkedList()
ll.appendleft(1)
ll.append(2)
assert list(ll) == [1, 2] if __name__ == '__main__':
test_linked_list()
test_linked_list_append()
test_linked_list_reverse()
单链表(python)的更多相关文章
- 单链表-Python实现-jupyter->markdown 格式测试
单链表引入 顺序表 理解Python变量的本质: 变量存储的不是值,是值的地址 理解Python的 "="表示的是指向关系 案例: 交换a,b的值, a=10, b=20 a, b ...
- 【数据结构】单链表介绍及leetcode206题反转单链表python实现
题目传送门:https://leetcode-cn.com/problems/reverse-linked-list/ 文章目录 单链表介绍 链表 概念 种类 优缺点 单链表(slist) leetc ...
- 数据结构学习--单链表(python)
概念 链表(linked_list)是物理存储单元上非连续的.非顺序的存储结构,数据元素的逻辑顺序 是通过链表的指针地址实现,每个元素包含两个结点,一个是存储元素的数据域 (内存空间) ,另一个是指向 ...
- 数据结构:单链表结构字符串(python版)添加了三个新功能
#!/urs/bin/env python # -*- coding:utf-8 -*- #异常类 class stringTypeError(TypeError): pass #节点类 class ...
- 数据结构:单链表结构字符串(python版)改进
此篇文章的replace实现了字符串类的多次匹配,但依然有些不足. 因为python字符串对象为不变对象,所以replace方法并不修改原先的字符串,而是返回修改后的字符串. 而此字符串对象时用单链表 ...
- 数据结构:单链表结构字符串(python版)
#!/urs/bin/env python # -*- coding:utf-8 -*- #异常类 class stringTypeError(TypeError): pass #节点类 class ...
- Python 之简易单链表
单链表的基本要素有 2 个,数据项和连接项.这两项在 Python 中可以通过对象及其属性来实现. class Node: def __init__ (self, data): self.data = ...
- python 数据结构之单链表的实现
链表的定义: 链表(linked list)是由一组被称为结点的数据元素组成的数据结构,每个结点都包含结点本身的信息和指向下一个结点的地址.由于每个结点都包含了可以链接起来的地址信息,所以用一个变量就 ...
- python实现数据结构单链表
#python实现数据结构单链表 # -*- coding: utf-8 -*- class Node(object): """节点""" ...
随机推荐
- jvm(3)---常用监控工具指令
1.jps 查看jvm中运行的进程(获取对应pid) 参数:默认-V(大写) -v: 列出jvm启动参数. ---------------------------------- 2.jstack pi ...
- 一文带你全面了解RxJava
工作需要,刚好在学习 RxJava网络请求框架,网上搜了一些 关于RxJava 的教程,但都并不是很好理解,所幸最后找到了几篇有助于初学者了解 RxJava 的文章,于是结合自己的理解,重新整理成一篇 ...
- 020 Android 常用颜色对应表
1.Android colors.xml常用颜色汇总 <?xml version="1.0" encoding="utf-8"?> <reso ...
- Struts笔记2
Struts2-配置文件result元素 作用:为动作指定结果视图 name属性:逻辑视图的名称,对应着动作方法的返回值.默认值是success type属性:结果类型,指的就是用什么方式转到定义的页 ...
- 以php中的比较运算符操作整型,浮点型,字符串型,布尔型和空类型
字符,数字,特殊符号的比较依赖ASC II表,本表原先有127个,后来又扩充了一些,里面包含了奇奇奇怪的符号. ASC II表 https://baike.baidu.com/item/ASCII/3 ...
- Python--列表中字符串按照某种规则排序的方法
作者:禅在心中 出处:http://www.cnblogs.com/pinking/ 本文版权归作者和博客园共有,欢迎批评指正及转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接, ...
- T-SQL学习笔记
学习T-SQL时记录的笔记,记得并不全也不详细 if和while语句 declare @age int select @age = DATEDIFF(year,stuAge,getdate()) fr ...
- linux下的打包与解包的简单总结
.tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压缩!) ---------------------- ...
- Vue组件全局/局部注册
全局注册 main.js中创建 Vue.component('button-counter', { data: function () { return { count: 0 } }, templat ...
- jmeter保存返回数据到csv
添加一个线程组,然后右键选择“正则表达式提取器” 配置正则表达式: 添加添加后置处理器beanshell postprocessor: 保存提取的数据: 代码: FileWriter fstream ...