Reverse Morris traversal using Threaded Binary Tree
Last Updated :
06 Nov, 2024
Given a binary tree, the task is to perform reverse in-order traversal using Morris Traversal.
Example:
Input:

Output: 3 1 5 2 4
Explanation: Inorder traversal (Right->Root->Left) of the tree is 3 1 5 2 4
Input:

Output: 6 5 10 6 8 10 7 1
Explanation: Inorder traversal (Right->Root->Left) of the tree is 6 5 10 6 8 10 7 1
Morris (In-order) Traversal is a tree traversal algorithm that operates without recursion or a stack by creating temporary links in the tree, using them to traverse nodes, and then restoring the tree’s original structure.
Prerequisites :
- Morris Traversals
- Threaded Binary Trees: In a binary tree with
n
nodes, n + 1
NULL pointers waste memory. Threaded binary trees use these NULL pointers to store useful information.- Left-threaded: Stores ancestor information in NULL left pointers.
- Right-threaded: Stores successor information in NULL right pointers.
- Fully-threaded: Stores both predecessor (NULL left) and successor (NULL right) information.
Reverse Morris Traversal:
This is the inverse process of Morris Traversals , where links to the in-order descendants are created, used to traverse in reverse order, and then removed to restore the original structure.
Approach:
- Initialize Current as root.
- While current is not NULL :
- If current has no right child, visit the current node and move to the left child of current.
- Else, find the in-order successor of current node. In-order successor is the left most node in the right subtree or right child itself.
- If the left child of the in-order successor is NULL, set current as the left child of its in-order successor and move current node to its right.
- Else, if the threaded link between the current and it's in-order successor already exists, set left pointer of the in-order successor as NULL, visit Current node and move to its left child node.
C++
// C++ program to print reverse inorder
// traversal using morris traversal.
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* left;
Node* right;
Node(int x) {
data = x;
left = nullptr;
right = nullptr;
}
};
// Function to perform reverse
// morris traversal.
vector<int> reverseMorris(Node* root) {
vector<int> ans;
Node* curr = root;
while (curr != nullptr) {
// if right child is null, append
// curr node and move to left node.
if (curr->right == nullptr) {
ans.push_back(curr->data);
curr = curr->left;
}
else {
// Find the inorder successor of curr
Node* succ = curr->right;
while (succ->left != nullptr
&& succ->left != curr)
succ = succ->left;
// Make curr as the left child of its
// inorder successor and move to
// right node.
if (succ->left == nullptr) {
succ->left = curr;
curr = curr->right;
}
// Revert the changes made in the 'if' part to
// restore the original tree i.e., fix the left
// child of successor and move to left node.
else {
succ->left = nullptr;
ans.push_back(curr->data);
curr = curr->left;
}
}
}
return ans;
}
int main() {
// Constructed binary tree is
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node *root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
vector<int> res = reverseMorris(root);
for (auto num: res) cout << num << " ";
cout << endl;
return 0;
}
Java
// Java program to print reverse inorder
// traversal using morris traversal.
import java.util.ArrayList;
import java.util.List;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = null;
right = null;
}
}
class GfG {
// Function to perform reverse
// morris traversal.
static List<Integer> reverseMorris(Node root) {
List<Integer> ans = new ArrayList<>();
Node curr = root;
while (curr != null) {
// if right child is null, add
// curr node and move to left node.
if (curr.right == null) {
ans.add(curr.data);
curr = curr.left;
} else {
// Find the inorder successor of curr
Node succ = curr.right;
while (succ.left != null && succ.left != curr) {
succ = succ.left;
}
// Make curr as the left child of its
// inorder successor and move to
// right node.
if (succ.left == null) {
succ.left = curr;
curr = curr.right;
}
// Revert the changes made in the 'if' part to
// restore the original tree i.e., fix the left
// child of successor and move to left node.
else {
succ.left = null;
ans.add(curr.data);
curr = curr.left;
}
}
}
return ans;
}
public static void main(String[] args) {
// Constructed binary tree is
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
List<Integer> res = reverseMorris(root);
for (int num : res) {
System.out.print(num + " ");
}
System.out.println();
}
}
Python
# Python program to print reverse inorder
# traversal using morris traversal.
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Function to perform reverse
# morris traversal.
def reverseMorris(root):
ans = []
curr = root
while curr is not None:
# if right child is null, append
# curr node and move to left node.
if curr.right is None:
ans.append(curr.data)
curr = curr.left
else:
# Find the inorder successor of curr
succ = curr.right
while succ.left is not None and \
succ.left != curr:
succ = succ.left
# Make curr as the left child of its
# inorder successor and move to
# right node.
if succ.left is None:
succ.left = curr
curr = curr.right
# Revert the changes made in the 'if' part to
# restore the original tree i.e., fix the left
# child of successor and move to left node.
else:
succ.left = None
ans.append(curr.data)
curr = curr.left
return ans
if __name__ == "__main__":
# Constructed binary tree is
# 1
# / \
# 2 3
# / \ / \
# 4 5 6 7
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
res = reverseMorris(root)
print(" ".join(map(str, res)))
C#
// C# program to print reverse inorder
// traversal using morris traversal.
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = null;
right = null;
}
}
class GfG {
// Function to perform reverse
// morris traversal.
static List<int> reverseMorris(Node root) {
List<int> ans = new List<int>();
Node curr = root;
while (curr != null) {
// if right child is null, add
// curr node and move to left node.
if (curr.right == null) {
ans.Add(curr.data);
curr = curr.left;
} else {
// Find the inorder successor of curr
Node succ = curr.right;
while (succ.left != null && succ.left != curr) {
succ = succ.left;
}
// Make curr as the left child of its
// inorder successor and move to
// right node.
if (succ.left == null) {
succ.left = curr;
curr = curr.right;
}
// Revert the changes made in the 'if' part to
// restore the original tree i.e., fix the left
// child of successor and move to left node.
else {
succ.left = null;
ans.Add(curr.data);
curr = curr.left;
}
}
}
return ans;
}
static void Main(string[] args) {
// Constructed binary tree is
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
List<int> res = reverseMorris(root);
Console.WriteLine(string.Join(" ", res));
}
}
JavaScript
// JavaScript program to print reverse inorder
// traversal using morris traversal.
class Node {
constructor(x) {
this.data = x;
this.left = null;
this.right = null;
}
}
// Function to perform reverse
// morris traversal.
function reverseMorris(root) {
const ans = [];
let curr = root;
while (curr !== null) {
// if right child is null, add
// curr node and move to left node.
if (curr.right === null) {
ans.push(curr.data);
curr = curr.left;
} else {
// Find the inorder successor of curr
let succ = curr.right;
while (succ.left !== null && succ.left !== curr) {
succ = succ.left;
}
// Make curr as the left child of its
// inorder successor and move to
// right node.
if (succ.left === null) {
succ.left = curr;
curr = curr.right;
}
// Revert the changes made in the 'if' part to
// restore the original tree i.e., fix the left
// child of successor and move to left node.
else {
succ.left = null;
ans.push(curr.data);
curr = curr.left;
}
}
}
return ans;
}
// Constructed binary tree is
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
const root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
const res = reverseMorris(root);
console.log(res.join(" "));
Time Complexity : O(n), where n is the number of nodes in the tree. Each node will be traversed at most 3 times.
Auxiliary Space : O(1)