<think>
我们正在处理关于完全二叉树路径的问题。根据引用[2],有一个示例代码,它根据输入的数组创建完全二叉树,并找出所有路径和等于给定值的路径。这个代码包括以下几个部分:
1. 定义树节点类 `TreeNode`。
2. 根据列表创建完全二叉树的函数 `creatBTree`。
3. 找出和为某一值的所有路径的函数 `findPath`,其中使用深度优先搜索(DFS)进行先序遍历,并记录路径。
用户的需求是查找用Python实现完全二叉树路径的代码。我们可以参考引用[2]中的代码,并将其整理为清晰的代码示例。同时,根据引用[3]和[4]中的一些概念,我们可以补充说明完全二叉树的性质和路径查找的方法。
注意:引用[2]中的代码假设输入的是层序遍历的数组,其中使用'#'表示空节点(但在示例输入中并没有使用,而是直接使用数字和空格)。然而,在创建二叉树时,它使用了完全二叉树的性质:对于下标为`index`的节点,其左子节点下标为`2*index+1`,右子节点为`2*index+2`。
我们将按照以下步骤编写代码:
1. 定义树节点。
2. 根据数组创建完全二叉树的函数。
3. 实现从根节点到叶子的路径查找,并筛选出路径和等于目标值的路径。
但是,注意引用[2]中的代码在查找路径时,将路径以列表的列表形式返回,并按路径长度从大到小排序(这个排序不是必须的,可以根据需求调整)。
另外,引用[4]中给出了另一种遍历二叉树的方法(求左叶子之和),但我们的重点是路径查找。
下面给出完整的代码示例,并加上必要的注释:
```python
# 定义树节点
class TreeNode:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
# 根据列表创建完全二叉树
def createBTree(data, index):
# 如果索引超出列表长度,或者该位置为'#'(代表空节点),则返回None
if index >= len(data) or data[index] == '#':
return None
# 创建当前节点
node = TreeNode(data[index])
# 递归创建左子树和右子树
node.left = createBTree(data, 2 * index + 1)
node.right = createBTree(data, 2 * index + 2)
return node
# 找出和为某一值的所有路径(从根到叶子)
def findPath(root, target):
# 用于存储所有符合条件的路径
result = []
# 当前路径
path = []
# 递归辅助函数
def dfs(node, current_sum):
if not node:
return
# 将当前节点加入路径
path.append(int(node.val))
current_sum += int(node.val)
# 如果是叶子节点,检查路径和是否等于目标值
if not node.left and not node.right:
if current_sum == target:
result.append(path[:]) # 注意要用切片复制当前路径
# 递归遍历左右子树
dfs(node.left, current_sum)
dfs(node.right, current_sum)
# 回溯,从路径中移除当前节点
path.pop()
dfs(root, 0)
# 返回结果,可以按需求排序,这里按路径长度从大到小排序(原代码做法)
return sorted(result, key=len, reverse=True)
# 主函数
if __name__ == "__main__":
# 输入目标值
target = int(input("请输入目标值: "))
# 输入节点值,用空格分隔,空节点用'#'表示(但注意完全二叉树的表示,通常空节点在末尾可以省略,但中间空节点需用'#'占位)
data = input("请输入节点值(空格分隔): ").split()
# 创建完全二叉树
root = createBTree(data, 0)
# 查找路径
paths = findPath(root, target)
print("所有路径和等于{}的路径:".format(target))
for p in paths:
print(p)
```
注意:
1. 该代码假设输入的数据是字符串,需要转换为整数。如果节点值为非数字,则需要进行调整。
2. 在创建二叉树时,如果某个位置是空节点,则输入'#',否则输入节点的值。但是,在完全二叉树中,空节点通常出现在末尾,所以中间非空节点后的空节点需要用'#'占位,以保证位置的正确性。
3. 路径查找使用深度优先遍历(DFS),并在到达叶子节点时检查路径和。
4. 在递归回溯时,需要将当前节点从路径中移除(即`path.pop()`)。
示例输入和输出:
输入目标值:22
输入节点值:5 4 8 11 # 13 4 7 2 # # 5 1
(注意:这里用空格分隔,其中'#'表示空节点)
这个输入对应的二叉树如下(示例):
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
那么路径和为22的路径有:[5,4,11,2] 和 [5,8,4,5]
但是注意,我们的代码在创建树时,需要严格按照完全二叉树的形式,所以输入数组应该是层序遍历的,并且中间空节点用'#'占位。在这个例子中,输入数组应该是:['5','4','8','11','#','13','4','7','2','#','#','5','1']。
运行代码后,将输出这两条路径。
此外,我们还可以参考引用[3]中提到的完全二叉树可以用非嵌套列表(数组)实现,因为完全二叉树具有性质:节点i的左子节点在2i,右子节点在2i+1(这里索引从1开始)。但在我们的代码中,索引是从0开始的,所以左子节点在2*i+1,右子节点在2*i+2。
以上代码和说明应该能够满足用户的需求。
§§相关问题§§
1. 如何优化查找二叉树中和为某一值的路径的算法?
2. 在非完全二叉树中如何实现路径查找?
3. 完全二叉树在数据结构中还有哪些应用?
</think>
以下是使用Python实现完全二叉树路径查找的代码,重点解决"从根节点到叶子节点路径和等于给定值"的问题:
```python
# 定义树节点类
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = int(val) # 确保值为整数类型
self.left = left
self.right = right
# 根据列表创建完全二叉树
def create_complete_binary_tree(data, index=0):
"""
根据层序遍历列表创建完全二叉树
:param data: 层序遍历的节点值列表 (空节点用'#'表示)
:param index: 当前节点在列表中的索引
:return: 构建好的二叉树根节点
"""
if index >= len(data) or data[index] == '#':
return None
# 创建当前节点
node = TreeNode(data[index])
# 递归创建左右子树 (利用完全二叉树的性质)
node.left = create_complete_binary_tree(data, 2 * index + 1)
node.right = create_complete_binary_tree(data, 2 * index + 2)
return node
# 查找所有路径和等于目标值的路径
def find_paths_with_sum(root, target_sum):
"""
查找所有从根到叶子节点路径和等于目标值的路径
:param root: 二叉树根节点
:param target_sum: 目标路径和
:return: 符合条件的路径列表
"""
if not root:
return []
result = [] # 存储所有符合条件的路径
def dfs(node, current_path, current_sum):
# 将当前节点添加到路径
current_path.append(node.val)
current_sum += node.val
# 如果是叶子节点且路径和等于目标值
if not node.left and not node.right:
if current_sum == target_sum:
result.append(current_path.copy())
# 递归遍历左右子树
if node.left:
dfs(node.left, current_path, current_sum)
if node.right:
dfs(node.right, current_path, current_sum)
# 回溯:移除当前节点
current_path.pop()
dfs(root, [], 0)
return result
# 主函数
if __name__ == "__main__":
# 示例输入:目标值 22,层序遍历序列 [5,4,8,11,'#',13,4,7,2,'#','#',5,1]
target = 22
data = input("请输入层序遍历序列(空格分隔,空节点用#表示): ").split()
target = int(input("请输入目标路径和: "))
# 构建完全二叉树
root = create_complete_binary_tree(data)
# 查找路径
paths = find_paths_with_sum(root, target)
# 输出结果
if paths:
print(f"找到 {len(paths)} 条路径和为 {target} 的路径:")
for i, path in enumerate(paths, 1):
print(f"路径 {i}: {' -> '.join(map(str, path))}")
else:
print(f"未找到路径和为 {target} 的路径")
```
### 代码说明
1. **TreeNode类**:
- 表示二叉树节点,包含值和左右子节点指针
- 值自动转换为整数类型,确保计算正确性
2. **create_complete_binary_tree函数**:
- 利用完全二叉树的性质:节点i的左子节点在$2i+1$,右子节点在$2i+2$
- 支持空节点表示(使用'#'占位)
- 时间复杂度:$O(n)$,每个节点只访问一次
3. **find_paths_with_sum函数**:
- 使用深度优先搜索(DFS)遍历所有路径
- 采用回溯法记录当前路径
- 到达叶子节点时检查路径和是否等于目标值
- 时间复杂度:$O(n)$,每个节点访问一次
4. **输入输出示例**:
```
# 输入
请输入层序遍历序列(空格分隔,空节点用#表示): 5 4 8 11 # 13 4 7 2 # # 5 1
请输入目标路径和: 22
# 输出
找到 2 条路径和为 22 的路径:
路径 1: 5 -> 4 -> 11 -> 2
路径 2: 5 -> 8 -> 4 -> 5
```
### 完全二叉树的性质
- 除最后一层外,其他层节点数达到最大值
- 最后一层节点从左到右连续排列
- 节点$i$的:
- 父节点索引:$\lfloor (i-1)/2 \rfloor$
- 左子节点索引:$2i+1$
- 右子节点索引:$2i+2$
### 应用场景
1. 优先队列实现(二叉堆)
2. 堆排序算法
3. 高效优先级调度系统
4. 图算法中的最短路径计算(如Dijkstra算法)[^3]