单链表(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): """节点""" ...
随机推荐
- matlab绘制直方图的方法
直接上代码,利用hist绘制频次直方图和频率直方图... %rand Fs=1000;N=10000; t=0:1/Fs:(N-1)/Fs; X1=rand(1,length(t)); subplot ...
- Head First Design Patterns HeadFirst 设计模式
OO原则是我们的目标,而设计模式是我们的做法. 策略模式 (Strategy) 在软件开发上,一直不变的真理是"change".不管软件设计的多好,一段时间之后,总是要成长与改变, ...
- python基础篇(一)
PYTHON基础篇(一) 变量 赋值 输入,输出和导入 A:输入 B:输出 C:导入 运算符 A:算数运算符 B:比较运算符 C:赋值运算符 D:位运算符 E:逻辑运算符 F:成员运算符 G:身份运算 ...
- LeetCode 792. 匹配子序列的单词数(Number of Matching Subsequences)
792. 匹配子序列的单词数 792. Number of Matching Subsequences 相似题目 392. 判断子序列
- [转帖]Linux下主机间文件传输命令
Linux下主机间文件传输命令 https://yq.aliyun.com/articles/53631?spm=a2c4e.11155435.0.0.580ce8ef4Q9uzs SCP命令: ...
- JSP的部分知识(一)
通过Servlet进行整个网站的开发是可以的. 不过在Servlet中输出html代码,特别是稍微复杂一点的html代码,就会给人一种很酸爽的感觉. 如果能够直接使用Html代码,然后在html中写j ...
- youku项目总结(粗略总结)
一.ORM 之前我们都是以文件保存的形式存储数据,这次我们用的是数据库结合python使用,用到 ORM:关系型映射 类>>数据库的一张表 对象>>表一条记录 对象.属性> ...
- matplotlib实例笔记
下面的图型是在一幅画布上建立的四个球员相关数据的极坐标图 关于这个图的代码如下: #_*_coding:utf-8_*_ import numpy as np import matplotlib.py ...
- Scratch编程:初识Scratch及编程工具安装(一)
“ Scratch是一款由美国麻省理工学院(MIT)设计开发的少儿编程工具.” Scratch采用可视化.模块化的编程方式,非常适合青少年作为初次接触编程的工具和语言来学习,进而用其编写充满趣味的小程 ...
- libhura的建立
libharu 是一个开源的导出pdf的库,在编译libharu需要用到zlib库和libpng库(libpng 依赖于zlib库).如果项目中不需要导出带有图片的pdf,可以将涉及到"pn ...