单链表(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): """节点""" ...
随机推荐
- mysql的HA及openstack和k8s区别
数据库HA(Hight Availability) mysql自身支持主主/主备部署,多主(>2),一主多备 galera mariadb集群:多主相互备份 修改容器的启动配置 修改Docker ...
- CF1227D Optimal Subsequences
思路: 首先对于单个查询(k, p)来说,答案一定是a数组中的前k大数.如果第k大的数字有多个怎么办?取索引最小的若干个.所以我们只需对a数组按照值降序,索引升序排序即可. 多个查询怎么办?离线处理. ...
- React-native/React 公告滚动组件(原生代码)
编写不易, 希望大家点赞 import React, {PureComponent} from 'react'; import {Animated, Easing, View} from 'react ...
- [ClickOnce] - Win10 管理员模式下无法安装 ClickOnce 之解决
Issue Windows 10 管理员模式下,点击 ClickOnce 安装程序无反应. 解决 1. 按 WIN+R 键打开“运行”窗口,输入 “gpedit.msc" 打开组策略.2. ...
- 05 IO流(三)——IO流标准流程
流程 选择源 选择合适的流 操作 关闭流:先打开的后关闭 演示 import java.io.File; import java.io.InputStream; import java.io.File ...
- 【SCALA】3、模拟电路
Simulation package demo17 abstract class Simulation { type Action = () => Unit case class WorkIte ...
- SQLSERVER远程链接Oracle数据库
原文地址: http://blog.sina.com.cn/s/blog_45eaa01a0102ywuk.html 使用SQL链接服务器远程访问Oracle数据库 在本机上通过SQL数据库的链接 ...
- Kubernetes 学习笔记(一):基础概念
个人笔记,仅本人查阅使用,不保证正确. 零.微服务 微服务架构专注于应用解耦合,通过将应用彻底地组件化和服务化,每个微服务只包含一个非常小的功能,比如权限管理.日志收集等等.由这一组微服务组合起来,提 ...
- Mysql union和union all用法
1: 什么时候用union和union all ? 我们经常会碰到这样的应用,两个表的数据按照一定的查询条件查询出来以后,需要将结果合并到一起显示出来,这个时候 就需要用到union和union ...
- 什么是RAID(磁盘阵列)
RAID全称Redundant Array of Independent Disk,即独立冗余磁盘阵列.RAID技术由加州大学伯克利分校1987年提出,最初是为了组合小的廉价磁盘来代替大的昂贵磁盘,同 ...