一、不定组输入模版
1. 读取多组数据,直到EOF
python
import sys
def solve():
# 方法1:使用sys.stdin读取所有行
for line in sys.stdin:
line = line.strip()
if not line:
continue
# 处理每一行
nums = list(map(int, line.split()))
print(nums)
# 方法2:使用input()读取(同样读到EOF)
while True:
try:
line = input().strip()
if not line:
continue
# 处理数据
print(line)
except EOFError:
break
if __name__ == "__main__":
solve()
2. 先读取组数T,再处理T组数据
python
def solve():
T = int(input())
for _ in range(T):
# 读取每组数据
n, m = map(int, input().split())
arr = list(map(int, input().split()))
# 处理数据
print(n, m, arr)
if __name__ == "__main__":
solve()
二、整行输入模版
python
def solve():
# 读取一行字符串
s = input().strip()
# 读取一行整数(空格分隔)
arr = list(map(int, input().split()))
# 读取一行字符(无分隔)
chars = list(input().strip())
# 读取整数,但某些行可能是空的或者有多个空格
import sys
line = sys.stdin.readline().strip()
if line:
nums = list(map(int, line.split()))
print(s, arr, chars)
if __name__ == "__main__":
solve()
三、二叉树的输入与建立
python
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def build_tree_from_list(nums):
"""
从层序遍历的数组构建二叉树
nums: list, 包含None表示空节点
例如: [1, 2, 3, None, 5, None, 4]
"""
if not nums or nums[0] is None:
return None
root = TreeNode(nums[0])
queue = [root]
i = 1
while queue and i < len(nums):
node = queue.pop(0)
# 左子节点
if i < len(nums) and nums[i] is not None:
node.left = TreeNode(nums[i])
queue.append(node.left)
i += 1
# 右子节点
if i < len(nums) and nums[i] is not None:
node.right = TreeNode(nums[i])
queue.append(node.right)
i += 1
return root
def input_binary_tree():
"""
从标准输入读取二叉树
输入格式: 1 2 3 null 5 null 4
"""
line = input().strip().split()
nums = [int(x) if x != 'null' and x != 'None' else None for x in line]
return build_tree_from_list(nums)
# 示例使用
if __name__ == "__main__":
root = input_binary_tree()
四、普通树的建立
python
from collections import defaultdict
class TreeNode:
def __init__(self, val=0):
self.val = val
self.children = []
def build_tree_from_edges():
"""
方法1:根据边建立树
输入格式:第一行 n(节点数)
接下来 n-1 行,每行 u v (表示u-v的一条边)
默认根节点为1
"""
n = int(input())
graph = defaultdict(list)
for _ in range(n - 1):
u, v = map(int, input().split())
graph[u].append(v)
graph[v].append(u)
# 构建树结构(有向树,默认根为1)
def build_tree(parent, node):
tree_node = TreeNode(node)
for child in graph[node]:
if child != parent:
tree_node.children.append(build_tree(node, child))
return tree_node
root = build_tree(-1, 1)
return root
def build_tree_from_parent_array():
"""
方法2:根据父节点数组建立树
输入格式:第一行 n(节点数)
第二行 n 个整数,第i个表示节点i的父节点(根节点父节点为-1)
"""
n = int(input())
parents = list(map(int, input().split()))
nodes = [TreeNode(i) for i in range(n)]
root = None
for i, parent in enumerate(parents):
if parent == -1:
root = nodes[i]
else:
nodes[parent].children.append(nodes[i])
return root
# 示例使用
if __name__ == "__main__":
root1 = build_tree_from_edges()
root2 = build_tree_from_parent_array()
五、图的读入与建立
python
from collections import defaultdict
def build_graph():
"""
图的输入与建立
常见输入格式:
第一行: n m (n个节点,m条边)
接下来m行: u v (表示无向边)
或: u v w (表示带权边)
"""
# 1. 邻接表(最常用)
n, m = map(int, input().split())
graph = defaultdict(list)
# 无向无权图
for _ in range(m):
u, v = map(int, input().split())
graph[u].append(v)
graph[v].append(u)
# 有向无权图
# for _ in range(m):
# u, v = map(int, input().split())
# graph[u].append(v)
# 无向有权图
# for _ in range(m):
# u, v, w = map(int, input().split())
# graph[u].append((v, w))
# graph[v].append((u, w))
return graph, n
def build_graph_adj_matrix():
"""
邻接矩阵建图
"""
n, m = map(int, input().split())
# 初始化邻接矩阵,无边用0或INF表示
INF = float('inf')
graph = [[INF] * n for _ in range(n)]
for i in range(n):
graph[i][i] = 0
for _ in range(m):
u, v, w = map(int, input().split())
u -= 1 # 如果节点从1开始,转为0索引
v -= 1
graph[u][v] = w
graph[v][u] = w # 无向图
return graph, n
# 示例使用
if __name__ == "__main__":
graph, n = build_graph()
六、DFS 模版
1. 二叉树DFS
python
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
# 前序遍历
def preorder(root):
if not root:
return
print(root.val, end=' ') # 处理当前节点
preorder(root.left)
preorder(root.right)
# 中序遍历
def inorder(root):
if not root:
return
inorder(root.left)
print(root.val, end=' ')
inorder(root.right)
# 后序遍历
def postorder(root):
if not root:
return
postorder(root.left)
postorder(root.right)
print(root.val, end=' ')
2. 图的DFS
python
from collections import defaultdict
def dfs_graph(graph, node, visited):
"""
图DFS遍历
graph: 邻接表
node: 当前节点
visited: 访问标记数组
"""
visited[node] = True
print(node, end=' ') # 处理当前节点
for neighbor in graph[node]:
if not visited[neighbor]:
dfs_graph(graph, neighbor, visited)
def dfs_iterative(graph, start):
"""
图DFS非递归实现
"""
visited = set()
stack = [start]
while stack:
node = stack.pop()
if node not in visited:
visited.add(node)
print(node, end=' ') # 处理当前节点
# 逆序加入邻居以保持顺序
for neighbor in reversed(graph[node]):
if neighbor not in visited:
stack.append(neighbor)
print()
# 使用示例
if __name__ == "__main__":
n = 5
graph = {
0: [1, 2],
1: [0, 3, 4],
2: [0],
3: [1],
4: [1]
}
visited = [False] * n
dfs_graph(graph, 0, visited) # 输出: 0 1 3 4 2
3. DFS回溯模版(常见题型)
python
def dfs_backtrack(path, options, result):
"""
通用回溯模版
path: 当前路径
options: 可选列表
result: 结果集
"""
# 终止条件
if 满足条件:
result.append(path[:]) # 注意要拷贝
return
# 遍历选择
for i, option in enumerate(options):
# 做选择
path.append(option)
# 递归(通常需要更新options)
dfs_backtrack(path, options[:i] + options[i+1:], result)
# 撤销选择
path.pop()
七、BFS 模版
1. 二叉树BFS
python
from collections import deque
def bfs_binary_tree(root):
"""
二叉树层序遍历
返回二维列表,每层一个列表
"""
if not root:
return []
result = []
queue = deque([root])
while queue:
level_size = len(queue)
current_level = []
for _ in range(level_size):
node = queue.popleft()
current_level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(current_level)
return result
2. 图BFS(最短路径模版)
python
from collections import deque, defaultdict
def bfs_graph(graph, start):
"""
图BFS遍历
"""
visited = set([start])
queue = deque([start])
while queue:
node = queue.popleft()
print(node, end=' ') # 处理当前节点
for neighbor in graph[node]:
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
print()
def bfs_shortest_path(graph, start, target):
"""
BFS求最短路径(无权图)
返回最短距离和路径
"""
if start == target:
return 0, [start]
visited = {start}
queue = deque([(start, [start])]) # (节点, 路径)
while queue:
node, path = queue.popleft()
for neighbor in graph[node]:
if neighbor == target:
return len(path), path + [neighbor]
if neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, path + [neighbor]))
return -1, [] # 不可达
# 使用示例
if __name__ == "__main__":
graph = {
0: [1, 2],
1: [0, 3, 4],
2: [0],
3: [1],
4: [1]
}
bfs_graph(graph, 0) # 输出: 0 1 2 3 4
dist, path = bfs_shortest_path(graph, 0, 4)
print(f"距离: {dist}, 路径: {path}") # 距离: 2, 路径: [0, 1, 4]
八、拓扑排序模版
1. Kahn算法(BFS实现)
python
from collections import deque, defaultdict
def topological_sort_kahn(graph, n):
"""
Kahn算法实现拓扑排序
graph: 邻接表
n: 节点数
返回排序结果,如果存在环则返回空列表
"""
# 计算入度
indegree = [0] * n
for u in graph:
for v in graph[u]:
indegree[v] += 1
# 将所有入度为0的节点入队
queue = deque([i for i in range(n) if indegree[i] == 0])
result = []
while queue:
u = queue.popleft()
result.append(u)
for v in graph[u]:
indegree[v] -= 1
if indegree[v] == 0:
queue.append(v)
# 如果结果数量不等于节点数,说明存在环
if len(result) != n:
return [] # 存在环
return result
def input_and_topological_sort():
"""
输入图并拓扑排序
输入格式:
第一行: n m (n个节点,m条边,节点编号0到n-1)
接下来m行: u v (表示u->v的有向边)
"""
n, m = map(int, input().split())
graph = defaultdict(list)
for _ in range(m):
u, v = map(int, input().split())
graph[u].append(v)
result = topological_sort_kahn(graph, n)
if not result:
print("存在环,无法拓扑排序")
else:
print("拓扑排序结果:", result)
if __name__ == "__main__":
input_and_topological_sort()
2. DFS实现拓扑排序
python
def topological_sort_dfs(graph, n):
"""
DFS实现拓扑排序
需要处理三种状态:
- 0: 未访问
- 1: 正在访问(在递归栈中)
- 2: 已访问完成
"""
visited = [0] * n # 0=未访问, 1=访问中, 2=已完成
result = []
has_cycle = [False]
def dfs(u):
if visited[u] == 1: # 发现环
has_cycle[0] = True
return
if visited[u] == 2: # 已处理
return
visited[u] = 1 # 标记为访问中
for v in graph[u]:
dfs(v)
visited[u] = 2 # 标记为已完成
result.append(u)
for i in range(n):
if visited[i] == 0:
dfs(i)
if has_cycle[0]:
return [] # 存在环
return result[::-1] # 逆序得到拓扑序
九、综合实战模版(树+DFS+BFS+拓扑)
python
from collections import deque, defaultdict
import sys
# ========== 二叉树定义 ==========
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
# ========== 输入处理 ==========
def read_input():
"""读取所有输入,返回行列表"""
lines = []
for line in sys.stdin:
line = line.strip()
if line:
lines.append(line)
return lines
# ========== 建树 ==========
def build_tree_from_level_order(nums):
"""从层序遍历数组构建二叉树"""
if not nums or nums[0] is None:
return None
root = TreeNode(nums[0])
queue = deque([root])
i = 1
while queue and i < len(nums):
node = queue.popleft()
if i < len(nums) and nums[i] is not None:
node.left = TreeNode(nums[i])
queue.append(node.left)
i += 1
if i < len(nums) and nums[i] is not None:
node.right = TreeNode(nums[i])
queue.append(node.right)
i += 1
return root
# ========== DFS ==========
def dfs_tree(root):
"""二叉树DFS(前序)"""
if not root:
return
print(root.val, end=' ')
dfs_tree(root.left)
dfs_tree(root.right)
# ========== BFS ==========
def bfs_tree(root):
"""二叉树层序遍历"""
if not root:
return []
result = []
queue = deque([root])
while queue:
level = []
for _ in range(len(queue)):
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(level)
return result
# ========== 图的拓扑排序 ==========
def topological_sort(n, edges):
"""拓扑排序,edges为边列表[(u,v),...]"""
graph = defaultdict(list)
indegree = [0] * n
for u, v in edges:
graph[u].append(v)
indegree[v] += 1
queue = deque([i for i in range(n) if indegree[i] == 0])
result = []
while queue:
u = queue.popleft()
result.append(u)
for v in graph[u]:
indegree[v] -= 1
if indegree[v] == 0:
queue.append(v)
return result if len(result) == n else []
# ========== 主函数 ==========
if __name__ == "__main__":
# 示例:读取树并遍历
# 输入:1 2 3 null null 4 5
arr = [1, 2, 3, None, None, 4, 5]
root = build_tree_from_level_order(arr)
print("DFS前序遍历:", end=' ')
dfs_tree(root) # 输出: 1 2 3 4 5
print()
print("BFS层序遍历:", bfs_tree(root)) # 输出: [[1], [2, 3], [4, 5]]
# 示例:拓扑排序
n = 4
edges = [(0, 1), (0, 2), (1, 3), (2, 3)]
print("拓扑排序:", topological_sort(n, edges)) # 输出: [0, 1, 2, 3]
总结:华为机考要点
根据图片内容,华为机考重点在于:
- 不考链表,但树和图是重点
- 输入输出要熟练掌握,特别是整行读取和不定期输入
- DFS/BFS 是核心算法,常考题
- 拓扑排序 是图论中的高频考点
这些模版代码覆盖了图片中提到的所有内容,建议:
- 多练习建图、建树的代码
- DFS/BFS的递归和迭代写法都要会
- 拓扑排序的两种实现(Kahn和DFS)都要掌握
- 熟悉ACM模式下的输入输出处理