返回

从根到叶:揭开二叉树垂序遍历的秘密花园

前端

纵览垂序世界:探索二叉树的垂直投影

想象一下一棵枝繁叶茂的二叉树,它的枝条向各个方向延伸。垂序遍历就是将这棵树投影到一个二维平面上,并将树中各节点按其在投影中的垂直位置从左到右依次排列。

算法寻路:深度优先 VS 宽度优先

要完成垂序遍历,有两种算法可供选择:深度优先搜索和宽度优先搜索。

深度优先搜索:沿着枝干逐层深入

深度优先搜索就像一个探索者,它从根节点出发,沿着树的一条枝干逐层向下探索,直到到达叶节点。在返回时,它再沿着另一条枝干继续探索,直到遍历完整棵树。

宽度优先搜索:逐层横向扩展

宽度优先搜索则像一个园丁,它从根节点出发,先遍历根节点的所有子节点,再遍历子节点的子节点,以此类推,逐层向外扩展,直到遍历完整棵树。

实战演练:示例代码详解

现在,让我们通过一个示例代码来具体了解垂序遍历的实现。

深度优先搜索(DFS)代码:

def verticalTraversalDFS(root):
    # 存储节点及其对应列
    node_col = {}
    
    # 辅助函数,用于 DFS 遍历
    def dfs(node, col, level):
        if not node:
            return
        
        # 更新节点及其对应列
        if col not in node_col:
            node_col[col] = []
        node_col[col].append((level, node.val))
        
        # 递归遍历左右子节点
        dfs(node.left, col-1, level+1)
        dfs(node.right, col+1, level+1)
    
    # 从根节点开始 DFS 遍历
    dfs(root, 0, 0)
    
    # 整理结果,按列从小到大输出
    result = []
    for col in sorted(node_col.keys()):
        result.append([val for _, val in sorted(node_col[col])])
    return result

宽度优先搜索(BFS)代码:

def verticalTraversalBFS(root):
    # 存储节点及其对应列
    node_col = {}
    
    # 队列,用于 BFS 遍历
    queue = [(root, 0, 0)]
    
    # BFS 遍历
    while queue:
        node, col, level = queue.pop(0)
        if not node:
            continue
        
        # 更新节点及其对应列
        if col not in node_col:
            node_col[col] = []
        node_col[col].append((level, node.val))
        
        # 将左右子节点加入队列
        if node.left:
            queue.append((node.left, col-1, level+1))
        if node.right:
            queue.append((node.right, col+1, level+1))
    
    # 整理结果,按列从小到大输出
    result = []
    for col in sorted(node_col.keys()):
        result.append([val for _, val in sorted(node_col[col])])
    return result

总结:纵横捭阖,领略算法之美

无论是深度优先搜索还是宽度优先搜索,都是解决垂序遍历问题的有效算法。深度优先搜索沿着枝干逐层深入,而宽度优先搜索逐层横向扩展。每种算法都有其独特的优势,选择哪种算法取决于具体情况。

后记:登高望远,探索算法的无穷魅力

垂序遍历只是算法世界中的沧海一粟,还有更多精彩的算法等待着我们去探索。从简单的排序算法到复杂的机器学习算法,算法无处不在,它们是计算机科学的基石。让我们继续前行,登高望远,领略算法的无穷魅力。