全网最适合入门的面向对象编程教程:45 Python 实现常见数据结构-链表、树
全网最适合入门的面向对象编程教程:45 Python 实现常见数据结构-链表、树、哈希表、图和堆https://img2024.cnblogs.com/blog/2591203/202408/2591203-20240825003614492-408022634.png
摘要:
数据结构是计算机科学中的一种组织和存储数据的方式,它决定了数据的访问方式和操作效率,数据结构的选择和实现对程序的性能和设计至关重要。本文重要讲述了如何利用 Python 语言和内置库实现常见数据结构。
原文链接:
FreakStudio的博客
往期推荐:
学嵌入式的你,还不会面向对象??!
全网最适合入门的面向对象编程教程:00 面向对象设计方法导论
全网最适合入门的面向对象编程教程:01 面向对象编程的根本概念
全网最适合入门的面向对象编程教程:02 类和对象的 Python 实现-利用 Python 创建类
全网最适合入门的面向对象编程教程:03 类和对象的 Python 实现-为自定义类添加属性
全网最适合入门的面向对象编程教程:04 类和对象的Python实现-为自定义类添加方法
全网最适合入门的面向对象编程教程:05 类和对象的Python实现-PyCharm代码标签
全网最适合入门的面向对象编程教程:06 类和对象的Python实现-自定义类的数据封装
全网最适合入门的面向对象编程教程:07 类和对象的Python实现-范例注解
全网最适合入门的面向对象编程教程:08 类和对象的Python实现-@property装饰器
全网最适合入门的面向对象编程教程:09 类和对象的Python实现-类之间的关系
全网最适合入门的面向对象编程教程:10 类和对象的Python实现-类的继承和里氏更换原则
全网最适合入门的面向对象编程教程:11 类和对象的Python实现-子类调用父类方法
全网最适合入门的面向对象编程教程:12 类和对象的Python实现-Python利用logging模块输出程序运行日志
全网最适合入门的面向对象编程教程:13 类和对象的Python实现-可视化阅读代码神器Sourcetrail的安装利用
全网最适合入门的面向对象编程教程:全网最适合入门的面向对象编程教程:14 类和对象的Python实现-类的静态方法和类方法
全网最适合入门的面向对象编程教程:15 类和对象的 Python 实现-__slots__魔法方法
全网最适合入门的面向对象编程教程:16 类和对象的Python实现-多态、方法重写与开闭原则
全网最适合入门的面向对象编程教程:17 类和对象的Python实现-鸭子范例与“file-like object“
全网最适合入门的面向对象编程教程:18 类和对象的Python实现-多重继承与PyQtGraph串口数据绘制曲线图
全网最适合入门的面向对象编程教程:19 类和对象的 Python 实现-利用 PyCharm 主动生成文件解释和函数解释
全网最适合入门的面向对象编程教程:20 类和对象的Python实现-组合关系的实现与CSV文件保存
全网最适合入门的面向对象编程教程:21 类和对象的Python实现-多文件的组织:模块module和包package
全网最适合入门的面向对象编程教程:22 类和对象的Python实现-异常和语法错误
全网最适合入门的面向对象编程教程:23 类和对象的Python实现-抛出异常
全网最适合入门的面向对象编程教程:24 类和对象的Python实现-异常的捕获与处理
全网最适合入门的面向对象编程教程:25 类和对象的Python实现-Python判定输入数据范例
全网最适合入门的面向对象编程教程:26 类和对象的Python实现-上下文管理器和with语句
全网最适合入门的面向对象编程教程:27 类和对象的Python实现-Python中异常层级与自定义异常类的实现
全网最适合入门的面向对象编程教程:28 类和对象的Python实现-Python编程原则、哲学和规范大汇总
全网最适合入门的面向对象编程教程:29 类和对象的Python实现-断言与防御性编程和help函数的利用
全网最适合入门的面向对象编程教程:30 Python的内置数据范例-object根类
全网最适合入门的面向对象编程教程:31 Python的内置数据范例-对象Object和范例Type
全网最适合入门的面向对象编程教程:32 Python的内置数据范例-类Class和实例Instance
全网最适合入门的面向对象编程教程:33 Python的内置数据范例-对象Object和范例Type的关系
全网最适合入门的面向对象编程教程:34 Python的内置数据范例-Python常用复合数据范例:元组和定名元组
全网最适合入门的面向对象编程教程:35 Python的内置数据范例-文档字符串和__doc__属性
全网最适合入门的面向对象编程教程:36 Python的内置数据范例-字典
全网最适合入门的面向对象编程教程:37 Python常用复合数据范例-列表和列表推导式
全网最适合入门的面向对象编程教程:38 Python常用复合数据范例-利用列表实现堆栈、队列和双端队列
全网最适合入门的面向对象编程教程:39 Python常用复合数据范例-集合
全网最适合入门的面向对象编程教程:40 Python常用复合数据范例-摆列和enum模块的利用
全网最适合入门的面向对象编程教程:41 Python常用复合数据范例-队列(FIFO、LIFO、优先级队列、双端队列和环形队列)
全网最适合入门的面向对象编程教程:42 Python常用复合数据范例-collections容器数据范例
全网最适合入门的面向对象编程教程:43 Python常用复合数据范例-扩展内置数据范例
全网最适合入门的面向对象编程教程:44 Python内置函数与魔法方法-重写内置范例的魔法方法
更多精彩内容可看:
给你的 Python 加加速:一文速通 Python 并行计算
一文搞懂 CM3 单片机调试原理
肝了半个月,嵌入式技能栈大汇总出炉
电子计算机类比赛的“武林秘笈”
一个MicroPython的开源项目集锦:awesome-micropython,包含各个方面的Micropython工具库
Avnet ZUBoard 1CG开辟板—深度学习新选择
SenseCraft 部署模型到Grove Vision AI V2图像处理模块
文档和代码获取:
可访问如下链接举行对文档下载:
https://github.com/leezisheng/Doc
https://img2024.cnblogs.com/blog/2591203/202407/2591203-20240711215550373-1274223674.png
本文档重要介绍如何利用 Python 举行面向对象编程,需要读者对 Python 语法和单片机开辟具有根本相识。相比其他解说 Python 面向对象编程的博客或册本而言,本文档更加详细、侧重于嵌入式上位机应用,以上位机和下位机的常见串口数据收发、数据处理、动态图绘制等为应用实例,同时利用 Sourcetrail 代码软件对代码举行可视化阅读便于读者理解。
相干示例代码获取链接如下:https://github.com/leezisheng/Python-OOP-Demo
正文
数据结构根本知识
现实上,前文讲到的队列、列表、集合、字典等均属于数据结构的一部门。数据结构,作为一种代码结构,其焦点目的在于有序地存储与组织数据,进而简化信息的修改、导航与访问过程。它不仅决定了数据的收集方式、实现的功能以及数据间的相互关系,更在计算机科学和编程的各个范畴,如操作系统、前端开辟以及机器学习等,发挥着不可或缺的作用。数据结构是解决题目的高效且真实的关键构件。每一种数据结构都有其独特的适用场景和任务。
数据结构可划分为逻辑结构与物理结构两大类:
[*]逻辑结构:是指数据元素间逻辑关系的数据组织方式,这种关系侧重于元素间的相对位置,而与数据在计算机中的现实存储位置无关。
在逻辑结构的分类中,可以分为线性结构和非线性结构:
[*]物理结构:又称存储结构,描述的是数据逻辑结构在计算机存储空间中的具体实现情势。数据的逻辑结构通常可以映射为多种物理结构。物理结构是实现数据元素间逻辑关系的具体手段。一种逻辑结构可以根据现实需求转化为多种物理结构。常见的物理结构有:
[*]① 顺序存储,其特点是元素在内存中的存储顺序是连续的,线性表的元素通过一组连续的存储单位来存储。
[*]② 链式存储,在这种方式中,内存中的存储元素不必连续,每个元素节点包含数据元素和指向相邻元素的指针信息。
[*]③ 索引存储,除了存储节点信息,还通过附加的索引表来标识节点的内存地点,索引表由多个索引项构成。
[*]④ 散列存储,又称 Hash 存储,此中节点的存储地点由节点的关键码值直接决定。
接下来,我们将简要介绍如何利用面向对象编程的头脑和 Python 内置数据范例去实现其他的数据结构,留意该部门并非本书重点内容,以是这里只是浅近的讲一下数据结构,此中实当代码重要是资助读者理解而非现实应用。
Python 实现链表
链表是一种物理存储单位上非连续、非顺序的存储结构,是由很多雷同数据范例的数据项按照特定顺序排列而成的线性表。链表有一系列节点组成,所谓节点就是指链表中的每一个元素,每个节点包含两个数据,一个是存储元素的数据域(值),另一个是存储下一个节点地点的指针域。
https://img2024.cnblogs.com/blog/2591203/202409/2591203-20240905004248509-2098137823.png
链表中的第一个节点称为头节点,最后一个节点称为尾节点,此中尾节点的 next 指向为 null。链表可以是单链,也可以是双链,这取决于每个节点是只有一个指向下一个节点的指针,还是还有一个指向前一个节点的指针。你可以把链表想象成一条链;单个链接只与相邻的链接有一个连接,但全部链接一起形成一个更大的结构。
class Node:
def __init__(self, dataval=None):
self.dataval = dataval
self.nextval = None
class SLinkedList:
def __init__(self):
self.headval = None
list1 = SLinkedList()
list1.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")
_# Link first Node to second node_
list1.headval.nextval = e2
_# Link second Node to third node_
e2.nextval = e3链表具有以下上风:新元素插入和删除更高效、比数组更易于重组、高级数据结构 (如图形或树)都是基于链表的,缺点是:每个数据点的指针存储增加了内存利用量同时必须始终从头节点遍历链表以查找特定元素。
Python 实现树
树是另一种基于关系的数据结构,专门用于表现层次结构。与链表一样,它们也被 Node 对象填充,Node 对象包含一个数据值和一个或多个指针,用于定义其与直接节点的关系。每棵树都有一个根节点,全部其他节点都从根节点分付出来。根节点包含指向它正下方全部元素的指针,这些元素被称为它的子节点。这些子节点可以有它们本身的子节点。在同一层上的任何节点都称为同级节点。没有连接子节点的节点称为叶节点。
https://img2024.cnblogs.com/blog/2591203/202409/2591203-20240905004255008-691633042.png
我们平时用到最多的就是二叉树,二叉树最常见的应用是二叉搜索树。二叉搜索树擅长于搜索大量的数据集合,由于时间复杂度取决于树的深度而不是节点的数目。二叉树具有以下特点:
[*]左子树只包含元素小于根的节点。
[*]右子树只包含元素大于根的节点。
[*]左右子树也必须是二叉搜索树。他们必须以树的“根”来遵循上述规则。
[*]不能有重复的节点,即不能有两个节点具有雷同的值。
lass Node:
def __init__(self, data):
self.left = None
self.right = None
self.data = data
def insert(self, data):
_# Compare the new value with the parent node_
if self.data:
if data < self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
elif data > self.data:
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
else:
self.data = data
_# Print the tree_
def PrintTree(self):
if self.left:
self.left.PrintTree()
print( self.data),
if self.right:
self.right.PrintTree()
_# Use the insert method to add nodes_
root = Node(12)
root.insert(6)
root.insert(14)
root.insert(3)
root.PrintTree()树形结构的搜索效率高非常适合存储分层数据(如文件位置等),但仅仅适用于排序的列表,未排序的数据退化为线性搜索。
Python 实现哈希表
哈希表又叫散列表,哈希表是一种复杂的数据结构,能够存储大量信息并有效检索特定元素。此结构存储的是由键(key)和值(value)组成的数据,根据键直接访问存储在内存存储位置的数据结构。
https://img2024.cnblogs.com/blog/2591203/202409/2591203-20240905004313696-812216691.png
每个输入键都要经过一个哈希函数,该函数将其从初始情势转换为一个整数值,称为哈希。哈希函数必须始终从雷同的输入产生雷同的哈希,必须快速计算,并产生固定长度的值。Python 包含一个内置的 hash()函数,可以加速实现。然后,该表利用散列来查找所需值(称为存储桶)的一般位置。然后,程序只需要在这个子组中搜索所需的值,而不必搜索整个数据池。除了这个通用框架之外,根据应用程序的不同,哈希表也可能非常不同。有些可能答应来自不同数据范例的键,而有些可能有不同的设置桶或不同的散列函数。
下面是一个 Python 代码中的哈希表现例:
import pprint
class Hashtable:
def __init__(self, elements):
self.bucket_size = len(elements)
self.buckets = [[] for i in range(self.bucket_size)]
self._assign_buckets(elements)
def _assign_buckets(self, elements):
for key, value in elements: _#calculates the hash of each key_
hashed_value = hash(key)
index = hashed_value % self.bucket_size _# positions the element in the bucket using hash_
self.buckets.append((key, value)) _#adds a tuple in the bucket_
def get_value(self, input_key):
hashed_value = hash(input_key)
index = hashed_value % self.bucket_size
bucket = self.buckets
for key, value in bucket:
if key == input_key:
return(value)
return None
def __str__(self):
return pprint.pformat(self.buckets) _# pformat returns a printable representation of the object_
if __name__ == "__main__":
capitals = [
('France', 'Paris'),
('United States', 'Washington D.C.'),
('Italy', 'Rome'),
('Canada', 'Ottawa')
]
hashtable = Hashtable(capitals)
print(hashtable)
print(f"The capital of Italy is {hashtable.get_value('Italy')}"哈希表可以将任何情势的键隐藏为整数索引,对于大型数据集搜索非常有效,经常应用于用于频仍查询的大型数据库或根据关键字检索的系统。
Python 实现图
图是一种数据结构,用于表现数据极点(图的节点)之间关系的可视化。将极点连接在一起的链接称为边。边定义了哪些极点被连接,但没有指明它们之间的流向。每个极点与其他极点都有连接,这些连接以逗号分隔的列表情势保存在极点上。还有一种特殊的图叫做有向图,它定义了关系的方向,类似于链表。在建模单向关系或类似流程图的结构时,有向图很有资助。
在 Python 中,图的最佳实现方式是利用字典,每个极点的名称作为键,边列表作为值。
_# Create the dictionary with graph elements_
graph = { "a" : ["b","c"],
"b" : ["a", "d"],
"c" : ["a", "d"],
"d" : ["e"],
"e" : ["d"]
}
_# Print the graph _
print(graph)图在存储数据上有着比较复杂和高效的算法,分别有邻接矩阵 、邻接表、十字链表、邻接多重表、边集数组等存储结构。常见的图遍历算法就是广度优先算法和深度优先算法。它适用于网络或类似网络的结构建模,可以通过代码快速传达视觉信息,但是在大型图中很难理解极点链接同时从图表中剖析数据的时间昂贵。
Python 实现堆
堆比较特殊,是一种图的树形结构。被用于实现“优先队列”(priority queues),优先队列是一种数据结构,可以自由添加数据,但取出数据时要从最小值开始按顺 序取出。在堆的树形结构中,各个极点被称为“结点”(node),数据就存储在这些结点中。只要满足下面两个特点的树形结构就是堆:
[*]堆是一个完全二叉树(所谓完全二叉树就是除了最后一层其他层的节点个数都是满的)。
[*]堆中每一个节点的值都必须大于即是大概小于其子树中每一个节点的值。
https://img2024.cnblogs.com/blog/2591203/202409/2591203-20240905004326386-292836911.png
我们可以利用 heapq 模块实现一个适合与 Python 的列表一起利用的最小堆:
import heapq
from heapq_showtree import show_tree
from heapq_heapdata import data
heap = []
print('random :', data)
print()
for n in data:
print('add {:>3}:'.format(n))
heapq.heappush(heap, n)
show_tree(heap)里面有两个函数需要留意:
[*]heapq.heappush(heap, item):将值 item 推送到 heap,保持堆不变。
[*]heapq_showtree.show_tree(heap):用于展示树形结构。
https://img2024.cnblogs.com/blog/2591203/202409/2591203-20240905004335373-1073416235.png
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]