Morris trversal:trverse binary tree inorder withのrecursion and O(1)space

7014 ワード

参考:http://pthread.blog.163.com/blog/static/169308178201210112045787/
 
Most text book s ment that binary tree can be trversed using recursion or、using stack without recursion.The recursive procedue is simple to write、and the stack version use extra space. 
The's also a very well designed algorithm trat a binary tree inorder without recursion and yet use only O(1)space--Morris Traversal. 
In this trversal,we first create links to inorder success or and print the data using the links,and finally revert the changes to restore ortree.
 
1. Initialize current as root 
2. While current is not NULL
   If current does not have left child
      a) Print current’s data
      b) Go to the right, i.e., current = current->right
   Else
      a) Make current as right child of the rightmost node in current's left subtree
      b) Go to this left child, i.e., current = current->left
The algorithm is also very easy to implement ation:
templatevoid moris_trversal(bstststit-unodeit*root){bststunode t< T>*current=root;while(current){if(!current->left){std::couttdata<"current"""";current=current===="""""""";currentEdedededededededededededededededededededededededededededede""""""""""""""""""""""""""""""""""""""""""""""ナイト!=current){it=it->Right;if(!it->right){it->right=current;current=current->left;else{std::cout<data<";it->right=NULL;current=current->right;}
 
But however,this algorithm is not so easure to understand.Why every time we encounter a node that has both Right child and left child,we have to set current node a s Right child of the right most node of the currest Horrett stres. 
temporarly change the tree structure?
 
Here we give some pictures to demostrate this process:
 
Morris traversal: traverse binary tree inorder with no recursion and O(1) space_第1张图片
 
 At the beginning、we start from the root node of the tree as current.
 
 
 
 
 
 
 
 
 
Morris traversal: traverse binary tree inorder with no recursion and O(1) space_第2张图片
 
Second、we find that node 8(current)has both left and right child、so we set node 8 as right child of the right most node of the left subtree、that's node 7.
 
/*
    here current points to node 8,it to node 3
*/
bst_node_t<T>* it = current->left;
/*
    go to che right most child of node 3 that is node 7
*/
while (it->right && it->right != current) {
    it = it->right;
}
/*
    here it points to node 7, current to node 8
*/
if (!it->right) {
    /*
        set current(node 8) as right child of node 7, notice
        that node 8's left child pointer still points to node 3
     */
    it->right = current;
    /*
        current goes left, that is, current points to node 3
    */
    current = current->left;
}
 
Morris traversal: traverse binary tree inorder with no recursion and O(1) space_第3张图片
 
Repeat the process above、with current node 3、go left child of current node、that is node 1.The n we find that node 1 hasのright child. 
 
So we set node 3 as node 1's left right child and set current as node 1.Node 1 hasのleft child、so we gos into this piece of code、and set current as 3
 
if(!current->left){std::cout<data<""";;current=current->Right;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Morris traversal: traverse binary tree inorder with no recursion and O(1) space_第4张图片
As node 3 goes to its left most child and find itself,which means that we visit node 3 in the second time,so here we rester the tree by set node 1's right child to NULL,and visit node 3.
 
 
/currrrent=>node 3 it=>node 1*/bst nodeit=current->left;/*here we find thit->right=node 3=current so brek the loop*/while(it-right&it&it=light=it==========================================================================currrrrrrrrrrrrrrrrrrrrrentcucucucucucucurrent ft t}else{****we visit node 3 in the second time、thus print data*/std::cout<data<"""、/*adjust node 1's right child pointer to null as itオリジナリティbe*/it->right=NULL;/we corretty 3
 
 
Here we have covered each condition of Morris Traversal.The loop continues and the whole tree will be trversed and restored.