后序的莫里斯遍历
使用Morris Traversal执行后序树遍历。
例子:
Input: 1
/ \
2 3
/ \ / \
6 7 8 9
Output: 6 7 2 8 9 3 1
Input: 5
/ \
2 3
/ \ / \
4 N 8 9
Output: 4 2 8 9 3 5
方法:为 Postorder 执行 Morris Traversal 的方法类似于为 Preorder 执行 Morris 遍历,除了在左右节点链接之间进行交换。
- 创建一个向量并将当前初始化为根
- 虽然 current 不为 NULL
- 如果当前没有正确的孩子
- 按下向量中的当前键
向左走,即current = current->left
- 按下向量中的当前键
- 别的
- 在当前右子树中查找最左边的节点或左子节点 == 当前的节点。
- 如果当前没有左孩子
- 按下向量中的当前键
- 从最左边节点的左子节点开始成为当前节点
- 去这个右孩子,即current = current->right
- 别的
- 找到左孩子 == 当前
- 将左子节点更新为当前左子节点的 NULL
- 向左走,即current = current->left
- 如果当前没有正确的孩子
- 最后,我们反转向量并打印它。
下面是上述方法的实现
C++
// C++ program to perform
// Morris Traversal for Postorder
#include
using namespace std;
struct TreeNode {
int key;
TreeNode* left;
TreeNode* right;
TreeNode(int data)
{
key = data;
left = NULL;
right = NULL;
}
};
// Function to print vector
void print(vector& ans)
{
// Print the vector elements
for (auto x : ans) {
cout << x << " ";
}
}
// Postorder traversal
// Without recursion and without stack
vector postorderTraversal(TreeNode* root)
{
vector res;
TreeNode* current = root;
while (current != NULL) {
// If right child is null,
// put the current node data
// in res. Move to left child.
if (current->right == NULL) {
res.push_back(current->key);
current = current->left;
}
else {
TreeNode* predecessor = current->right;
while (predecessor->left != NULL
&& predecessor->left != current) {
predecessor = predecessor->left;
}
// If left child doesn't point
// to this node, then put in res
// this node and make left
// child point to this node
if (predecessor->left == NULL) {
res.push_back(current->key);
predecessor->left = current;
current = current->right;
}
// If the left child of inorder predecessor
// already points to this node
else {
predecessor->left = NULL;
current = current->left;
}
}
}
// reverse the res
reverse(res.begin(), res.end());
return res;
}
// Driver program
int main()
{
TreeNode* root = new TreeNode(10);
root->left = new TreeNode(20);
root->right = new TreeNode(30);
root->right->left = new TreeNode(40);
root->right->right = new TreeNode(50);
cout << "Morris(postorder) Traversal: ";
vector ans = postorderTraversal(root);
print(ans);
return 0;
}
Java
// Java program to perform
// Morris Traversal for Postorder
import java.util.*;
class GFG{
static class TreeNode {
int key;
TreeNode left;
TreeNode right;
TreeNode(int data)
{
key = data;
left = null;
right = null;
}
};
// Function to print vector
static void print(Vector ans)
{
// Print the vector elements
for (int x : ans) {
System.out.print(x+ " ");
}
}
// Postorder traversal
// Without recursion and without stack
static Vector postorderTraversal(TreeNode root)
{
Vector res = new Vector<>();
TreeNode current = root;
while (current != null)
{
// If right child is null,
// put the current node data
// in res. Move to left child.
if (current.right == null) {
res.add(current.key);
current = current.left;
}
else {
TreeNode predecessor = current.right;
while (predecessor.left != null
&& predecessor.left != current) {
predecessor = predecessor.left;
}
// If left child doesn't point
// to this node, then put in res
// this node and make left
// child point to this node
if (predecessor.left == null) {
res.add(current.key);
predecessor.left = current;
current = current.right;
}
// If the left child of inorder predecessor
// already points to this node
else {
predecessor.left = null;
current = current.left;
}
}
}
// reverse the res
Collections.reverse(res);
return res;
}
// Driver program
public static void main(String[] args)
{
TreeNode root = new TreeNode(10);
root.left = new TreeNode(20);
root.right = new TreeNode(30);
root.right.left = new TreeNode(40);
root.right.right = new TreeNode(50);
System.out.print("Morris(postorder) Traversal: ");
Vector ans = postorderTraversal(root);
print(ans);
}
}
// This code is contributed by 29AjayKumar
C#
// C# program to perform
// Morris Traversal for Postorder
using System;
using System.Collections.Generic;
public class GFG {
public class TreeNode {
public int key;
public TreeNode left;
public TreeNode right;
public TreeNode(int data) {
key = data;
left = null;
right = null;
}
};
// Function to print vector
static void print(List ans)
{
// Print the vector elements
foreach (int x in ans) {
Console.Write(x + " ");
}
}
// Postorder traversal
// Without recursion and without stack
static List postorderTraversal(TreeNode root) {
List res = new List();
TreeNode current = root;
while (current != null) {
// If right child is null,
// put the current node data
// in res. Move to left child.
if (current.right == null) {
res.Add(current.key);
current = current.left;
} else {
TreeNode predecessor = current.right;
while (predecessor.left != null && predecessor.left != current) {
predecessor = predecessor.left;
}
// If left child doesn't point
// to this node, then put in res
// this node and make left
// child point to this node
if (predecessor.left == null) {
res.Add(current.key);
predecessor.left = current;
current = current.right;
}
// If the left child of inorder predecessor
// already points to this node
else {
predecessor.left = null;
current = current.left;
}
}
}
// reverse the res
res.Reverse();
return res;
}
// Driver program
public static void Main(String[] args) {
TreeNode root = new TreeNode(10);
root.left = new TreeNode(20);
root.right = new TreeNode(30);
root.right.left = new TreeNode(40);
root.right.right = new TreeNode(50);
Console.Write("Morris(postorder) Traversal: ");
List ans = postorderTraversal(root);
print(ans);
}
}
// This code is contributed by Rajput-Ji
Javascript
输出
Morris(postorder) Traversal: 20 40 50 30 10
时间复杂度: O(N)
辅助空间: O(1)