Given the root of a binary tree, Find its Preorder traversal using Morris Traversal, i.e., without using recursion or a stack.
Examples:
Input:
Output: [1, 2, 4, 5, 3]
Explanation: Preorder traversal (Root->Left->Right) of the tree is 1, 2, 4, 5, 3.Input:
Output: [8, 1, 7, 10, 5, 10, 6, 6]
Explanation: Preorder traversal (Root->Left->Right) of the tree is 8, 1, 7, 10, 5, 10, 6, 6.
Approach:
The key idea is to temporarily establish links to a node’s inorder predecessor so that we can traverse the tree and print the data in preorder. After visiting the nodes, we revert these links to restore the tree to its original structure. Although the tree is temporarily modified during traversal, it remains unchanged once the traversal is complete.
Morris Preorder Traversal Steps
Start with root Node(curr) and for each node:
- If the node does not have a left child, Visit (store) the node and move to the right child.
- If the node has a left child, Find the inorder predecessor (rightmost node in the left subtree).
- If the predecessor’s right is NULL, Make the current node as the right child of its inorder predecessor (temporary link). Visit(store) the current node and Move to the left child.
- If the predecessor’s right points to the current node.Remove the temporary link (restore predecessor->right = NULL) and move to the right child.
- Repeat until curr becomes NULL.
#include <iostream>
#include <vector>
using namespace std;
// Node Structure
class Node {
public:
int data;
Node *left, *right;
Node(int x){
data = x;
left = right = nullptr;
}
};
vector<int> preOrder(Node* root) {
vector<int> res;
while (root) {
// If left child is null, store the current node
// data and move to right child
if (root->left == nullptr) {
res.push_back(root->data);
root = root->right;
}
else {
// Find inorder predecessor
Node* current = root->left;
while (current->right && current->right != root)
current = current->right;
// If the right child of inorder predecessor
// already points to this node
if (current->right == root) {
current->right = nullptr;
root = root->right;
}
// If right child doesn't point to this node
else {
res.push_back(root->data);
current->right = root;
root = root->left;
}
}
}
return res;
}
int main() {
// Constructing binary tree.
// 1
// / \
// 2 3
// / \
// 4 5
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);
vector<int> res = preOrder(root);
for (int data : res) {
cout << data << " ";
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100000
// Node Structure
struct Node {
int data;
struct Node* left;
struct Node* right;
};
// Morris Preorder Traversal
int* preOrder(struct Node* root, int* size) {
struct Node* curr = root;
int capacity = MAX_SIZE;
int* res = (int*)malloc(capacity * sizeof(int));
int count = 0;
while (curr != NULL) {
// If node has no left child
// Visit the node and move to right child
if (curr->left == NULL) {
if (count >= capacity) {
capacity *= 2;
res = (int*)realloc(res, capacity * sizeof(int));
}
res[count++] = curr->data;
curr = curr->right;
}
else {
// Find inorder predecessor
struct Node* prev = curr->left;
while (prev->right != NULL && prev->right != curr) {
prev = prev->right;
}
// If the right child of inorder predecessor
// already points to this node
if (prev->right == curr) {
prev->right = NULL;
curr = curr->right;
}
else {
// If right child doesn't point to this node
if (count >= capacity) {
capacity *= 2;
res = (int*)realloc(res, capacity * sizeof(int));
}
res[count++] = curr->data;
prev->right = curr;
curr = curr->left;
}
}
}
*size = count;
return res;
}
// Helper to create a new node
struct Node* createNode(int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
int main() {
// Constructing binary tree.
// 1
// / \
// 2 3
// / \
// 4 5
struct Node* root = createNode(1);
root->left = createNode(2);
root->right = createNode(3);
root->left->left = createNode(4);
root->left->right = createNode(5);
int size;
int* res = preOrder(root, &size);
for (int i = 0; i < size; i++) {
printf("%d ", res[i]);
}
free(res);
return 0;
}
import java.util.ArrayList;
// Node sturcture
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = right = null;
}
}
class GFG {
static ArrayList<Integer> preOrder(Node root) {
ArrayList<Integer> res = new ArrayList<>();
while (root != null) {
// If left child is null, print the current node
// data. Move to right child.
if (root.left == null) {
res.add(root.data);
root = root.right;
}
else {
// Find inorder predecessor
Node current = root.left;
while (current.right != null
&& current.right != root)
current = current.right;
// If the right child of inorder predecessor
// already points to this node
if (current.right == root) {
current.right = null;
root = root.right;
}
// If right child doesn't point to this
// node, then print this node and make right
// child point to this node
else {
res.add(root.data);
current.right = root;
root = root.left;
}
}
}
return res;
}
public static void main(String[] args) {
// Constructing binary tree.
// 1
// / \
// 2 3
// / \
// 4 5
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);
ArrayList<Integer> res = preOrder(root);
for (int data : res) {
System.out.print(data + " ");
}
}
}
# Node Structure
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
def preOrder(root):
res = []
while root:
# If left child is null, print the current
# node data. Move to right child.
if root.left is None:
res.append(root.data)
root = root.right
else:
# Find inorder predecessor
current = root.left
while current.right and current.right != root:
current = current.right
# If the right child of inorder predecessor
# already points to this node
if current.right == root:
current.right = None
root = root.right
# If right child doesn't point to this node, then print this
# node and make right child point to this node
else:
res.append(root.data)
current.right = root
root = root.left
return res
if __name__ == "__main__":
# Constructing binary tree.
# 1
# / \
# 2 3
# / \
# 4 5
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
res = preOrder(root)
for data in res:
print(data, end=" ")
using System;
using System.Collections.Generic;
// Node Structure
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = right = null;
}
}
class GFG {
static List<int> preOrder(Node root) {
List<int> res = new List<int>();
while (root != null) {
// If left child is null, print the current node
// data. Move to right child.
if (root.left == null) {
res.Add(root.data);
root = root.right;
}
else {
// Find inorder predecessor
Node current = root.left;
while (current.right != null
&& current.right != root)
current = current.right;
// If the right child of inorder predecessor
// already points to this node
if (current.right == root) {
current.right = null;
root = root.right;
}
// If right child doesn't point to this
// node, then print this node and make right
// child point to this node
else {
res.Add(root.data);
current.right = root;
root = root.left;
}
}
}
return res;
}
static void Main() {
// Constructing binary tree.
// 1
// / \
// 2 3
// / \
// 4 5
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);
List<int> res = preOrder(root);
foreach (int data in res) {
Console.Write(data + " ");
};
}
}
// Node Structure
class Node {
constructor(x) {
this.data = x;
this.left = this.right = null;
}
}
function preOrder(root) {
let res = []
while (root) {
// If left child is null, print
// the current node data. Move to right child.
if (root.left === null) {
res.push(root.data);
root = root.right;
}
else {
// Find inorder predecessor
let current = root.left;
while (current.right && current.right !== root)
current = current.right;
// If the right child of inorder predecessor
// already points to this node
if (current.right === root) {
current.right = null;
root = root.right;
}
// If right child doesn't point to this node,
// then print this node and make right child
// point to this node
else {
res.push(root.data);
current.right = root;
root = root.left;
}
}
}
return res;
}
//Driver Code
// Constructing binary tree.
// 1
// / \
// 2 3
// / \
// 4 5
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);
let res = preOrder(root);
console.log(...res);
Output
1 2 4 5 3
Time Complexity: O(n)
Auxiliary Space: O(1)

