📜  后序的莫里斯遍历

📅  最后修改于: 2022-05-13 01:57:17.388000             🧑  作者: Mango

后序的莫里斯遍历

使用Morris Traversal执行后序树遍历。

例子:

方法:为 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)