Python提供了几种内置的数据结构,可以用来存储和组织数据。以下是Python中常见的数据结构:列表,元组,字典,集合,字符串,栈,队列,树,图。我们将介绍这些数据结构,并举例说明。
- 列表(List):
- 列表是一个有序的、可变的序列,可以存储不同类型的元素。
- 使用方括号[]来定义列表,元素之间用逗号分隔。
fruits = ['apple', 'banana', 'orange', 'grape']
print(fruits) # 输出: ['apple', 'banana', 'orange', 'grape']
- 元组(Tuple):
- 元组是一个有序的、不可变的序列,可以存储不同类型的元素。
- 使用小括号()来定义元组,元素之间用逗号分隔。
point = (3, 4)
print(point) # 输出: (3, 4)
- 字典(Dictionary):
- 字典是一个无序的、可变的键值对集合。
- 使用大括号{}来定义字典,每个键值对用冒号:分隔,键值对之间用逗号分隔。
person = {'name': 'John', 'age': 25, 'city': 'New York'}
print(person) # 输出: {'name': 'John', 'age': 25, 'city': 'New York'}
- 集合(Set):
- 集合是一个无序的、可变的、不允许重复元素的集合。
- 使用大括号{}或set()函数来定义集合,元素之间用逗号分隔。
numbers = {1, 2, 3, 4, 5}
print(numbers) # 输出: {1, 2, 3, 4, 5}
- 字符串(String):
- 字符串是一个有序的、不可变的字符序列。
- 使用单引号''或双引号""来定义字符串。
message = 'Hello, World!'
print(message) # 输出: Hello, World!
- 栈(Stack):
- 栈是一种后进先出(LIFO)的数据结构。
- 可以使用列表来模拟栈,使用append()方法添加元素,使用pop()方法移除并返回最后一个元素。
stack = [1, 2, 3]
stack.append(4)
stack.append(5)
print(stack) # 输出: [1, 2, 3, 4, 5]
item = stack.pop()
print(item) # 输出: 5
print(stack) # 输出: [1, 2, 3, 4]
- 队列(Queue):
- 队列是一种先进先出(FIFO)的数据结构。
- 可以使用列表来模拟队列,使用append()方法添加元素,使用pop(0)方法移除并返回第一个元素。
- Python提供了queue模块,其中的Queue类实现了队列的功能。
from queue import Queuequeue = Queue()
queue.put(1)
queue.put(2)
queue.put(3)
print(queue.get()) # 输出: 1
print(queue.get()) # 输出: 2
print(queue.get()) # 输出: 3
- 树(Tree):
树是一种层次结构的数据结构,由节点(Node)和边(Edge)组成。树具有以下特点:
- 树有一个特殊的节点称为根节点(Root Node),它没有父节点。
- 除了根节点外,每个节点都有且仅有一个父节点。
- 从根节点到任意节点的路径是唯一的。
- 树可以递归地定义为子树的集合,每个子树也是一棵树。
常见的树的类型包括:
- 二叉树(Binary Tree):每个节点最多有两个子节点,称为左子节点和右子节点。
- 二叉搜索树(Binary Search Tree):二叉树的一种,满足左子树的所有节点的值小于根节点,右子树的所有节点的值大于根节点。
- 平衡二叉树(AVL Tree):二叉搜索树的一种,满足左子树和右子树的高度差不超过1。
- 红黑树(Red-Black Tree):平衡二叉树的一种,通过引入颜色属性来维护树的平衡性。
下面是一个二叉树的例子:
class TreeNode:def __init__(self, value):self.val = valueself.left = Noneself.right = Noneroot = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
- 图(Graph):
图是一种由节点(Node)和边(Edge)组成的数据结构,用于表示对象之间的关系。图可以是有向的(Directed Graph)或无向的(Undirected Graph)。图具有以下特点:
- 图由一组节点(顶点)和一组边组成。
- 边连接两个节点,表示它们之间的关系。
- 有向图中的边有方向,表示从一个节点到另一个节点的关系。
- 无向图中的边没有方向,表示两个节点之间的双向关系。
图可以用邻接矩阵(Adjacency Matrix)或邻接表(Adjacency List)来表示:
- 邻接矩阵:使用二维数组表示图,如果节点i和节点j之间有边,则matrix[i][j] = 1,否则为0。
- 邻接表:使用列表或字典表示图,每个节点都有一个列表或字典,存储与之相连的节点。
下面是一个使用邻接表表示无向图的完整例子:
def dfs(graph, start, visited=None):if visited is None:visited = set()visited.add(start)print(start, end=' ')for neighbor in graph[start]:if neighbor not in visited:dfs(graph, neighbor, visited)# 创建无向图
graph = {'A': ['B', 'C'],'B': ['A', 'D', 'E'],'C': ['A', 'F'],'D': ['B'],'E': ['B', 'F'],'F': ['C', 'E']
}# 深度优先搜索遍历
print("DFS traversal:")
dfs(graph, 'A') # 输出: A B D E F Cprint("\n")def bfs(graph, start):visited = set()queue = [start]visited.add(start)while queue:vertex = queue.pop(0)print(vertex, end=' ')for neighbor in graph[vertex]:if neighbor not in visited:queue.append(neighbor)visited.add(neighbor)# 广度优先搜索遍历
print("BFS traversal:")
bfs(graph, 'A') # 输出: A B C D E F
在这个例子中,我们使用字典来表示无向图。字典的键表示节点,对应的值是一个列表,存储与该节点相连的其他节点。
我们定义了两个遍历图的函数:
- dfs(graph, start, visited=None):深度优先搜索遍历
graph:表示图的邻接表
start:表示开始遍历的起始节点
visited:表示已访问过的节点集合,默认为None
- 函数使用递归的方式遍历图,先访问起始节点,然后递归访问其未访问过的相邻节点。
bfs(graph, start):广度优先搜索遍历
graph:表示图的邻接表
start:表示开始遍历的起始节点
- 函数使用队列来实现广度优先搜索,先将起始节点加入队列,然后不断取出队首节点,访问其未访问过的相邻节点,并将它们加入队列,直到队列为空。
在示例代码中,我们创建了一个包含6个节点的无向图,并分别使用深度优先搜索和广度优先搜索对图进行遍历。
深度优先搜索的输出结果为:A B D E F C
广度优先搜索的输出结果为:A B C D E F
这个例子展示了如何使用邻接表表示无向图,以及如何使用深度优先搜索和广度优先搜索对图进行遍历。
示例代码地址:
https://github.com/gzmusem/QuantExamples/tree/main/Examples07