后续遍历
后续遍历
后续遍历二叉树的节点顺序为 先遍历左子树,然后遍历右子树,最后遍历根节点。
左->右->根
graph TD
A((10)) --> B((5))
A --> C((15))
B --> D((2))
B --> E((7))
上述二叉树后续遍历的节点顺序为:
graph TD
classDef visited fill:#9f9,stroke:#333,stroke-width:4px;
A((10)) --> B((5))
A --> C((15))
B --> D((2))
B --> E((7))
class D visited
graph TD
classDef visited fill:#9f9,stroke:#333,stroke-width:4px;
A((10)) --> B((5))
A --> C((15))
B --> D((2))
B --> E((7))
class D,E visited
graph TD
classDef visited fill:#9f9,stroke:#333,stroke-width:4px;
A((10)) --> B((5))
A --> C((15))
B --> D((2))
B --> E((7))
class D,E,B visited
graph TD
classDef visited fill:#9f9,stroke:#333,stroke-width:4px;
A((10)) --> B((5))
A --> C((15))
B --> D((2))
B --> E((7))
class D,E,B,C visited
graph TD
classDef visited fill:#9f9,stroke:#333,stroke-width:4px;
A((10)) --> B((5))
A --> C((15))
B --> D((2))
B --> E((7))
class D,E,B,C,A visited
后续遍历的递归实现
func PostOrderTraversal(root *dfs.BinaryTreeNode) {
// 基本条件
if root == nil {
return
}
// 先遍历左子树
PostOrderTraversal(root.Left)
// 再遍历右子树
PostOrderTraversal(root.Right)
// 最后遍历根节点
fmt.Println(root.Data)
}
测试代码:
func TestPostorderTraversal(t *testing.T) {
a := dfs.NewTreeNode(10)
b := dfs.NewTreeNode(5)
c := dfs.NewTreeNode(2)
d := dfs.NewTreeNode(7)
e := dfs.NewTreeNode(15)
a.Left = b
a.Right = e
b.Left = c
b.Right = d
PostOrderTraversal(a)
} //output: 2 7 5 15 10
后续遍历的迭代实现
首先后续遍历的顺序为左->右->根,而前序遍历的顺序为根->左->右。我们只需要将前序遍历的变为根->右->左,然后将结果反转即可。
func postorderTraversal(root *dfs.BinaryTreeNode) []int {
if root == nil {
return []int{}
}
result := []int{}
stack := list.New()
stack.PushBack(root)
for stack.Len() > 0 {
element := stack.Back()
stack.Remove(element)
ev := element.Value.(*dfs.BinaryTreeNode)
result = append(result, ev.Data)
if ev.Left != nil {
stack.PushBack(ev.Left)
}
if ev.Right != nil {
stack.PushBack(ev.Right)
}
}
slices.Reverse(result)
return result
}