📜  数据结构 |树遍历 |问题 1(1)

📅  最后修改于: 2023-12-03 14:54:56.332000             🧑  作者: Mango

数据结构 | 树遍历 | 问题 1

什么是树遍历?

树遍历是一种遍历树结构的方式,将树的每个节点都访问一次,且仅访问一次。树遍历算法可以分为三种基本类型:前序遍历、中序遍历和后序遍历。

前序遍历

前序遍历算法是从根节点开始访问,按照“根节点-左子树-右子树”的顺序访问每个节点,具体步骤如下:

  1. 访问根节点
  2. 遍历左子树(如果左子树非空)
  3. 遍历右子树(如果右子树非空)

前序遍历的结果可以用递归或非递归的方式获得,其中递归的算法比较简单:

def pre_order_traversal(tree):
    if tree is not None:
        print(tree.value)
        pre_order_traversal(tree.left)
        pre_order_traversal(tree.right)

非递归的算法需要利用栈结构,具体步骤如下:

  1. 将根节点入栈
  2. 取出栈顶节点,访问该节点
  3. 将该节点的右子树入栈(如果右子树非空)
  4. 将该节点的左子树入栈(如果左子树非空)
  5. 重复步骤 2-4,直到栈为空

非递归的算法如下:

def pre_order_traversal(tree):
    stack = []
    stack.append(tree)
    while stack:
        cur_node = stack.pop()
        print(cur_node.value)
        if cur_node.right is not None:
            stack.append(cur_node.right)
        if cur_node.left is not None:
            stack.append(cur_node.left)
中序遍历

中序遍历算法是按照“左子树-根节点-右子树”的顺序遍历每个节点,具体步骤如下:

  1. 遍历左子树(如果左子树非空)
  2. 访问根节点
  3. 遍历右子树(如果右子树非空)

中序遍历的结果也可以用递归或非递归的方式获得,其中递归的算法如下:

def in_order_traversal(tree):
    if tree is not None:
        in_order_traversal(tree.left)
        print(tree.value)
        in_order_traversal(tree.right)

非递归的算法需要利用栈结构,具体步骤如下:

  1. 将根节点入栈
  2. 将当前节点的所有左子树入栈
  3. 取出栈顶节点,访问该节点
  4. 将当前节点移动到该节点的右子树上
  5. 重复步骤 2-4,直到当前节点为空并且栈已经为空

非递归的算法如下:

def in_order_traversal(tree):
    stack = []
    cur_node = tree
    while cur_node or stack:
        while cur_node:
            stack.append(cur_node)
            cur_node = cur_node.left
        cur_node = stack.pop()
        print(cur_node.value)
        cur_node = cur_node.right
后序遍历

后序遍历算法是按照“左子树-右子树-根节点”的顺序遍历每个节点,具体步骤如下:

  1. 遍历左子树(如果左子树非空)
  2. 遍历右子树(如果右子树非空)
  3. 访问根节点

后序遍历的结果也可以用递归或非递归的方式获得,其中递归的算法如下:

def post_order_traversal(tree):
    if tree is not None:
        post_order_traversal(tree.left)
        post_order_traversal(tree.right)
        print(tree.value)

非递归的算法比较复杂,需要利用栈结构和一个标记变量,具体步骤如下:

  1. 根节点入栈,并且标记该节点还没有被访问过
  2. 如果当前节点没有左子树和右子树,或者当前节点的左子树和右子树都已经被访问过了(即标记变量为真),那么访问该节点并弹出栈顶元素
  3. 右子树节点入栈,并且标记该节点还没有被访问过(如果右子树节点非空)
  4. 左子树节点入栈,并且标记该节点还没有被访问过(如果左子树节点非空)
  5. 重复步骤 2-4,直到栈为空

非递归的算法如下:

def post_order_traversal(tree):
    stack = [(tree, False)]
    while stack:
        cur_node, visited = stack.pop()
        if cur_node:
            if visited:
                print(cur_node.value)
            else:
                stack.append((cur_node, True))
                stack.append((cur_node.right, False))
                stack.append((cur_node.left, False))
总结

树遍历是一种重要的算法,适用于树的遍历、搜索、构建和转化等场景。前序遍历、中序遍历和后序遍历是树遍历的基本类型,掌握这三种遍历算法并能正确运用,可以有效提高程序员的算法水平。