ZZ Morris Traversal method Traversal binary tree (non-recursive, without Stack, O (1) space)

Source: Internet
Author: User

Reprint Source Http://www.cnblogs.com/AnnieKim/archive/2013/06/15/MorrisTraversal.html

Bloggers are very serious, reproduced here to prevent the loss of links

This paper mainly solves a problem, how to realize the pre-and post-sequential traversal of two-fork tree, there are two requirements:

1. O (1) spatial complexity, i.e. only constant space is used;

2. The shape of the two fork tree cannot be destroyed (the middle process allows the shape to be changed).

In general, there are two common methods for implementing the pre-order (preorder), middle order (inorder), and post-ordering (Postorder) Traversal of a two-fork tree: Recursion (Recursive) and iteration version (stack+iterative) using the stack implementation. Both methods are the spatial complexity of O (n) (the recursion itself occupies the stack space or the user-defined stack), so it does not meet the requirements. (The implementation of the middle order traversal using these two methods can be referred to here.) )

The Morris traversal method can do these two points, unlike the first two methods in which the method requires only O (1) space and can also be completed in O (n) time.

To traverse with O (1) space, the biggest difficulty is how to return to the parent node (assuming the node does not have a P-pointer to the parent node), because the stack cannot be used as a secondary space. To solve this problem, the Morris method uses the concept of the Clue two fork tree (threaded binary trees). In the Morris method, there is no need to assign pointers to the precursors (predecessor) and successors (successor) for each node, just use the left and right pointers in the leaf nodes to point to a precursor or successor under some sort of sequential traversal.

Morris only provides the method of the middle sequence traversal, which can be realized by a little modification on the basis of the middle sequence traversal, and then the next step will be more thoughtful. So let's start with the preface.

First define the two-fork tree node structure used in this article, which consists of val,left and right:

1 struct TreeNode {2     int val;3     TreeNode *left;4     TreeNode *right;5     TreeNode (int x): Val (x), left (NULL), R Ight (NULL) {}6};
First, the middle sequence traversal

Steps:

1. If the left child of the current node is empty, the current node is output and its right child is the current node.

2. If the left child of the current node is not empty, the current node in the left subtree of the current node is found in the precursor node under the middle sequence traversal.

A) If the right child of the precursor node is empty, set its right child to the current node. The current node is updated to the left child of the current node.

b) If the right child of the precursor node is the current node, reset its right child to empty (restore the tree's shape). Outputs the current node. The current node is updated to the right child of the current node.

3. Repeat the above 1, 2 until the current node is empty.

Icon:

For each iteration of the result (from left to right, top to bottom), cur represents the current node, and a dark node indicates that the node has been output.

Code:

1 void Inordermorristraversal (TreeNode *root) {2     TreeNode *cur = root, *prev = NULL; 3 while     (cur! = null) 4     {5         if (cur->left = = NULL)          //1.6         {7             printf ("%d", cur->val); 8             cur = cur->right; 9         }10         else11         {             //find predecessor13             prev = cur->left;14             while (prev->right = NULL && prev->right! = cur)                 prev = prev->right;16             if (prev->righ t = = NULL)   //2.a)             {                 prev->right = cur;20                 cur = cur->left;21             }22             Else                       // 2.b) @                 prev->right = null;25                 printf ("%d", cur->val);                 cur = cur->right;27             }         }29     }30}

Analysis of Complexity:

Space complexity: O (1), because only two auxiliary pointers are used.

Time complexity: O (n). Proving that the time complexity is O (n), the biggest doubt lies in finding the time complexity of the precursor nodes of all the nodes in the two-fork tree under the sequence traversal, that is, the following two lines of code:

1 while (prev->right! = NULL && prev->right! = cur) 2     prev = prev->right;

Intuitively, the complexity of it is O (NLGN), as the precursor node of a single node is related to the height of the tree. In fact, it takes only O (n) time to find the precursor node for all nodes. n nodes of the two-fork tree in a total of n-1, the whole process of a maximum of 2 times per edge, one is to locate a node, and another is to find a node above the precursor node, as shown, where the red is to locate a node, the black line is to find the precursor node. So the complexity is O (n).

Second, pre-sequence traversal

The pre-order traversal is similar to the middle-order traversal, where there is only one line in the code, and the difference is in the order of output.

Steps:

1. If the left child of the current node is empty, the current node is output and its right child is the current node.

2. If the left child of the current node is not empty, the current node in the left subtree of the current node is found in the precursor node under the middle sequence traversal.

A) If the right child of the precursor node is empty, set its right child to the current node. Output the current node (output here, which is different from the middle sequence traversal only one by one points). The current node is updated to the left child of the current node.

b) If the right child of the precursor node is the current node, reset its right child to null. The current node is updated to the right child of the current node.

3. Repeat the above 1, 2 until the current node is empty.

Icon:

Code:

1 void Preordermorristraversal (TreeNode *root) {2     TreeNode *cur = root, *prev = NULL; 3 while     (cur! = null) 4
   
    {5         if (cur->left = = NULL) 6         {7             printf ("%d", cur->val); 8             cur = cur->right; 9         }10         else11         {prev             = cur->left;13 while             (prev->right! = Null && prev->right! = cur)                 prev = prev->right;15             if (prev->right = = NULL) (18<)             c17/>printf ("%d", cur->val);  The only difference with inorder-traversal19                 prev->right = cur;20                 cur = cur->left;21             }22             Else23             {                 prev->right = null;25                 cur = cur->right;26             }27}28     }29}
   

Analysis of Complexity:

Both the time complexity and the spatial complexity are the same as in the case of the middle sequence traversal.

Third, post-sequential traversal

The subsequent traversal is slightly more complex, requiring a temporary node dump to root the left child. and a sub-process is required to output the various nodes on the path between the two nodes in reverse.

Steps:

The current node is set to temporary node dump.

1. If the left child of the current node is empty, then its right child is the current node.

2. If the left child of the current node is not empty, the current node in the left subtree of the current node is found in the precursor node under the middle sequence traversal.

A) If the right child of the precursor node is empty, set its right child to the current node. The current node is updated to the left child of the current node.

b) If the right child of the precursor node is the current node, reset its right child to null. The reverse output is from the left child of the current node to all nodes on this path of the precursor node. The current node is updated to the right child of the current node.

3. Repeat the above 1, 2 until the current node is empty.

Icon:

Code:

 1 void reverse (TreeNode *from, TreeNode *to)//Reverse the tree nodes ' from ' to '. 2 {3 if (from = =) 4 return; 5 TreeNode *x = from, *y = From->right, *z; 6 while (true) 7 { 8 Z = y->right; 9 Y->right = x;10 x = y;11 y = z;12 if (x = = to) break;14}15}16 17 void PrintReverse (treenode* from, TreeNode *to)//print the Reversed tree nodes "from" to "." (From , to): TreeNode *p = to;22 while (true) at $ {printf ("%d", p->val), if (p = = fr OM) break;27 p = p->right;28}29 reverse (to, from);}32-void Postordermorrist Raversal (TreeNode *root) {TreeNode dump (0); dump.left = root;36 TreeNode *cur = &dump, *prev = null;3          7 while (cur) (cur->left = = NULL) + {cur = cur->right;42}43 else44 {45            Prev = cur->left;46 while (prev->right! = NULL && prev->right! = cur) 47 Prev = prev->right;48 if (prev->right = = NULL) {Prev->righ t = cur;52 cur = cur->left;53}54 else55 {printr  Everse (Cur->left, prev); Call Print57 Prev->right = null;58 cur = cur->right;59}60}6 1}62}

Analysis of Complexity:

The spatial complexity is also O (1), and the time complexity is O (n), and the reverse output process simply increases the constant coefficient.

Note:

All of the above code and test code can be obtained from my GitHub.

Reference:

http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion-and-without-stack/
http://www.geeksforgeeks.org/morris-traversal-for-preorder/
Http://stackoverflow.com/questions/6478063/how-is-the-complexity-of-morris-traversal-on
http://blog.csdn.net/wdq347/article/details/8853371
Data structures and algorithms in C + + by Adam Drozdek

ZZ Morris Traversal method Traversal binary tree (non-recursive, without Stack, O (1) space)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.