Python 中的数据结构和算法

2024 年 8 月 29 日 | 阅读 15 分钟

本课程将作为 Python 数据结构和算法的简单介绍。通过实际且经过充分解释的示例,我们将介绍列表、集合、字典、元组等内置数据结构,以及一些用户自定义数据结构,如链表、树和图,以及一些常用的算法。

列表

同样,与其他编程语言中的数组和 Python 中的列表一样,它们都是以任何方式排列的项的集合。它允许列表中包含多种数据类型的元素。Python 的列表版本可与 C++ 的 vector 或 Java 的 ArrayList 相媲美。由于所有元素都必须重新定位,因此从列表的开头添加或删除元素是最昂贵的操作。如果预先分配的内存已用完,则在列表末尾插入和删除元素也可能变得昂贵。

代码

输出

The created Python list is: 
['Python', 'Data', 'Structures', 'Tutorial']
The multi-Dimensional list is: 
[['Python', 'Data'], ['Structures', 'Tutorial']]
Single element:  Data
Multiple elements (slicing):  ['Python', 'Data']
For nested lists:  Structures
Last element:  ['Structures', 'Tutorial']
Last two elements:  ['Tutorial', 'Structures']

元组

列表和 Python 元组是等效的,但与列表不同,元组是不可变的,这意味着一旦创建,我们就无法更改它们。与列表一样,元组可以包含多种类型的元素。

Python 元组是通过将一系列值组合在一起创建的。这些值由“逗号”分隔,无论是否使用括号。

代码

输出

The Python tuple is: 
('Python', 'Data', 'Structures', 'Tutorial')
Tuple using a List: 
Single element:  Data
Multiple elements (slicing):  ('Python', 'Data')
Last element:  Tutorial
Exception raised:  'tuple' object does not support item assignment

Set

Python 集合数据结构是一种可修改的、非重复的数据集合。集合主要用于成员资格筛选和删除冗余条目。这些过程使用哈希数据结构,这是一种常见的遍历、插入和删除元素的方法,通常需要 O(1) 时间。

代码

输出

The Python Set is: 
{'Python', 'Data', 'Tutorial', 'Structures'}
0 Python
1 Data
2 Tutorial
3 Structures
Intersection:  {'Python', 'Data'}
Union:  {1, 2, 'Structures', 'Python', 'Tutorial', 'Data'}

字典

一种称为 Python 字典的键值对格式化数据集合用于存储数据。此数据结构的时间复杂度为 O(1),与其他编程语言中的哈希表非常相似。Python 字典是使用键索引的。键的值可以是任何类型,即常量项,如字符串、整数、序列等。我们可以使用花括号 {} 或字典推导式来构建字典。

代码

输出

The Python Dictionary is: 
{'1': 'Python', '2': 'Data', '3': 'Structures', '4': 'Tutorial'}
Value of key 2 is:  Data
Using the get method:  Data

链表

链表是一种线性数据结构,其元素不存储在内存的连续位置。链表的元素通过指针连接。

指向链表第一个节点的指针用于表示链表。head 指的是顶节点。如果链表为空,则 head 的值为 NULL。在列表中,每个节点至少包含两个组件

  • 数据
  • 指向下一个节点的指针(或引用)

代码

输出

Python
Tutorial
Data Structures

链表是重要的数据结构。以下是链表的一些基本操作。

代码

输出

Linked list:
9 4 8 7 2 
After deleting a node:
9 4 7 2 
 4 is found in the list
Sorted Linked List: 
2 4 7 9 

Stack

栈是一种线性数据结构,它使用先进后出 (FILO) 或后进先出 (LIFO) 的顺序来存储对象。在栈中,一个项目仅从一端删除,而新项目则添加到另一端。Push 和 Pop 是插入和删除操作的常用名称。

栈的基本操作

我们可以使用一些基本操作对栈执行各种活动。

Push:此方法将一个项目添加到栈顶

Pop:此方法将从栈顶删除一个项目

IsEmpty:此方法检查栈是否为空。

IsFull:此方法检查栈是否已满。

Peek:此方法将返回栈顶元素而不删除它。

代码

输出

New stack after pushing:  [2]
New stack after pushing:  [2, 5]
New stack after pushing:  [2, 5, 3]
New stack after pushing:  [2, 5, 3, 1]
New stack after popping:  [2, 5, 3]
Last element of the stack:  3

Queue

队列是另一种与栈相似的线性数据结构,它以先进先出 (FIFO) 的顺序存储对象。队列以我们最近添加项目的顺序移除项目。任何用户等待访问服务的队列,其中最先到达的用户最先得到服务,都是队列的一个绝佳示例。

与队列相关的操作包括

Enqueue:将内容添加到队列。当队列已满时,定义溢出条件。将元素添加到队列的时间复杂度:O(1)

Dequeue:从队列中移除一个项目。项目的弹出顺序与入队顺序相同。如果队列为空,则称为下溢条件。获取队列的第一个项目的时间复杂度为 O(1)。

Rear:获取队列中的最后一个项目。获取队列最后一个项目的时间复杂度为 O(1)。

代码

输出

New queue after enqueuing:  [6]
New queue after enqueuing:  [6, 3]
New queue after enqueuing:  [3, 9]
Last element:  9

Python heapq 模块提供了堆数据结构,它主要用于描述优先队列。堆数据结构的特点是,每次弹出项目时,它总是返回最小的项目(最小堆)。在保持堆结构的同时,始终推送或弹出项目。此外,heap[0] 项始终返回最小值。它允许以 O(log n) 的时间检索和插入最小元素。

堆通常有两种类型

最大堆:最大堆数据结构根节点的键必须高于其子节点的键。对于二叉树中的每个子树,相同的条件应递归成立。

最小堆:最小堆的根节点的键应该是所有子节点键的最小键。对于二叉树中的每个子树,相同的条件应递归成立。

代码

输出

Heap array:  [6, 4, 5, 3, 8]
After deleting an item:  [8, 4, 6, 3]

二叉树

树是一种非线性分层数据结构,由节点和边组成。

一种称为二叉树的 Python 树数据结构允许每个父节点最多有两个子节点。二叉树在每个节点处有三个组件

  1. 数据元素
  2. 左子节点的地址
  3. 右子节点的地址

代码

输出

Pre-order traversal of the tree: 4 5 10 1 0 7 2 9 
In-order traversal of the tree: 10 1 5 0 4 2 9 7 
Post-order traversal of the tree: 1 10 0 5 9 2 7 4 

冒泡排序算法

一种称为冒泡排序的排序方法,它分析两个相邻的项,然后交换它们,直到达到所需的顺序。

在每次迭代中,列表的每个元素都会移动到列表的末尾。这类似于液体中的气泡浮到表面的行为。因此,它被称为冒泡排序。

代码

输出

Sorted List in Descending Order:
[9, 7, 5, 3, 2, 0] 

选择排序算法

一种称为选择排序的排序算法,它在每次迭代中选择未排序列表中的最大元素,并将其插入列表的开头。

代码

输出

Sorted List in Descending Order:
[97, 85, 35, 29, 23, 20]

快速排序算法

在称为快速排序的排序算法中,使用分治策略将数组分割成更小的子数组(从数组中选取一个项)。

在分割给定数组时,枢轴元素应设置得使大于枢轴元素的项位于右侧,而小于枢轴值的项则存储在左侧。

使用相同的方法来分割右子数组和左子数组。重复此过程,直到每个子数组只剩下一个元素。

此时,元素已排序。项目组合最终会创建一个排序数组。

代码

输出

Sorted List in Ascending Order:
[0, 1, 2, 3, 4, 7, 8, 9]

计数排序算法

一种称为计数排序的排序方法,它根据给定数组中每个不同元素出现的次数来排列给定数组的元素。排序是通过将数组元素的计数映射到我们创建的另一个数组的索引来完成的。此数组存储元素的计数。

代码

输出

Sorted list: 
[2, 2, 3, 4, 7, 7, 8, 9]

二分查找算法

二分查找是一种在已排序数组中查找元素位置的搜索算法。

在此方法中,元素始终在数组某一部分的中间进行搜索。

代码

输出

The element we searched for is present at: 4