(via Data Structures - Tree Traversal)

seen from China
seen from Australia
seen from United States

seen from Germany
seen from Ukraine

seen from Malaysia
seen from United States
seen from China
seen from Spain

seen from Türkiye
seen from China
seen from United States

seen from United States
seen from United States

seen from Ireland
seen from France
seen from United Kingdom
seen from United States

seen from United States
seen from United States
(via Data Structures - Tree Traversal)
Traversal is a process to visit all the nodes of a tree and may print their values too. Because all nodes are connected via edges (links) we always start from the root (head) node.
Morris Inorder Traversal
We can traverse a tree in the inorder fashion iteratively, using stack, but it consumes space. So, in this problem, we are going to traverse a tree without the linear space being used. This concept is called Morris Inorder Traversal or Threading in Binary trees. Example 2 / 1 3 / 4 5 4 1 5 2 3 3 / 1 4 / 2 5 1 3 2 4 5 Approach The idea is: we can traverse the tree without the space of a stack (or the auxiliary space of recursion) if we do not lose the address of any node we visited earlier without storing them in the memory. This approach is called Morris Inorder Traversal. But without any space allowed, how can one store the addresses of nodes? The idea is to change the structure of the tree in such a way, that after visiting some particular nodes of one subtree from the root node, we can get back to the root node to process its other subtree. Say we visited the left subtree completely, and add a pointer from some node of the left subtree to the root again. Now, we can process the right subtree by coming back to the original root. In Morris Inorder Traversal, we link the inorder predecessor of a root(in its left subtree) to itself.
This process of adding pointers (threads) from the inorder predecessor to root is called threading. Again, we don't want to disturb the structure of the tree, so we will design an algorithm that automatically deletes the links and unthreads the tree to retain its original structure. Algorithm - Initialize the current node as root of the tree. - Keep iterating till we reach the condition where the current node becomes NULL. - If the left subtree of the current root is NULL : - We can now print the root and move to the right subtree, so currentNode = currentNode->right. - If the left subtree of the current root is NOT NULL : - In this case, we unthread/thread the rightmost node in the left subtree(inorder predecessor) of the current node to itself - temp = currentNode->left; - While temp->right is NOT NULL or temp is NOT currentNode - temp = temp->right - If temp->right is NULL: - remove threading as temp->right = NULL - process the right subtree, currentNode = currentNode->right - If temp->right is NOT NULL: - thread this node as temp->right = currentNode - Process the left subtree now, currentNode = currentNode->left Implementation of Morris Inorder Traversal C++ Program #include using namespace std; struct treeNode { int value; treeNode *left , *right; treeNode(int x) { value = x; left = NULL; right = NULL; } }; void morrisInorder(treeNode* &root) { treeNode* currentNode = root; while(currentNode != NULL) { if(currentNode->left == NULL) { cout value right; } else { treeNode* temp = currentNode->left; while((temp->right != NULL) && (temp->right != currentNode)) temp = temp->right; if(temp->right == NULL) { temp->right = currentNode; //threading currentNode = currentNode->left; } else { cout value right = NULL; //unthreading currentNode = currentNode->right; } } } } int main() { treeNode* root = new treeNode(2); root->left = new treeNode(1); root->right = new treeNode(3); root->left->left = new treeNode(4); root->left->right = new treeNode(5); morrisInorder(root); return 0; } 4 1 5 2 3 Java Program class treeNode { int value; treeNode left, right; public treeNode(int x) { value = x; left = right = null; } } class BinaryTree { treeNode root; void MorrisInorder() { treeNode currentNode = root; while(currentNode != null) { if(currentNode.left == null) { System.out.print(currentNode.value + " "); currentNode = currentNode.right; } else { treeNode temp = currentNode; while(temp.right != null && temp.right != currentNode) temp = temp.right; if(temp.right == null) { temp.right = currentNode; currentNode = currentNode.left; } else { temp.right = null; System.out.print(currentNode.value + " "); currentNode = currentNode.right; } } } } public static void main(String args) { BinaryTree tree = new BinaryTree(); tree.root = new treeNode(2); tree.root.left = new treeNode(1); tree.root.left.left = new treeNode(4); tree.root.left.right = new treeNode(5); tree.root.right = new treeNode(3); tree.MorrisInorder(); } } 4 1 5 2 3 Complexity Analysis of Morris Inorder Traversal Time Complexity O(N), where N is the number of nodes in the tree. It's certain that we visit every node exactly 2 times, as they all go through the process of threading and unthreading. But, the time complexity remains linear. Space Complexity O(1), as we use constant space for declaring some variables. But, no other auxiliary space is used for any purpose. That's what Morris Inorder Traversal promises about. Read the full article
Breadth First Search
Breadth First Search (BFS) is a common algorithm used in tree/graph traversal. The most important thing to remember for BFS is the use of the queue.
The basic process for the algorithm is to enqueue the root, dequeue a node and examine it. If the node is what you're looking for, then terminate. If not, enqueue the node's unvisited children and mark each as visited and continue dequeuing, examining, and enqueuing till the queue is empty or the target node is found.
Java:
public void BFS(Node root){ Queue q = new LinkedList(); q.add(root); root.visited = true; while(!q.isEmpty()){ Node n = q.remove(); Node child = null; while((child=getUnvisitedChildNode(n)) != null){ child.visited = true; q.add(child); } } clearNodes(); //Clear visited property of nodes }