Constant space traversal Binary Tree

Source: Internet
Author: User

We know that traversing a binary tree requires an O (n) stack space (system stack or stack controlled by programmers) for both sequential traversal, central traversal, and post-sequential traversal ), or a queue of the O (n) size is required for hierarchical traversal. So how can we traverse in a constant space?

This article describes the Deutsch-Schorr-Waite algorithm. You can use constant space and linear time to traverse any graph. This article uses a binary tree as an example (a binary tree is a special directed graph ).

The key to the algorithm is Pointer inversion. When the access process traverses the subtree downward, it "reverses" the pointer it passes through: saves the address of the parent node in a pointer field of the current node. When the access process goes back up, the original values of all pointer fields are restored.

During the process of traversing a binary tree, for each accessed node, the Deutsch-Schorr-Waite algorithm first changes the left field to a reverse pointer pointing to the parent node, next, traverse down the left subtree. During the second access, the address of the parent node is moved to the right domain and the original value of the left domain is restored. Then, the address is traversed down along the right subtree. During the last access, the right field is restored to its original value. The access process returns the parent node through the address previously saved in the right field. For each node, we need an additional tag to indicate whether the parent pointer is stored in the left or right fields. So does this still require a single position for each node? Space is still O (n), but we can use the low position of the pointer field to save this flag bit.
For example, binary tree node Definition


Struct TreeNode
{
Int val;
TreeNode * left;
TreeNode * right;
};
In a 32-bit system, the size of the struct is 12 bytes. By default, the compiler places the variable of this struct in a multiple of 4 at the starting address, that is to say, the values of left and righ are both 0, so we can use these bits to avoid using the space of O (n. In this article, the cursor bit in the left field is used as the tag in the code.
The algorithm implementation code is as follows:


[Cpp]
# Pragma pack (4)
Struct TreeNode
{
Int val;
TreeNode * left;
TreeNode * right;
};
 
Void Visit (TreeNode * node)
{
Printf ("% d \ n", node-> val );
}
 
Void Traversal (TreeNode * root)
{
If (root = NULL)
Return;
TreeNode * previous = NULL;
TreeNode * current = root;
TreeNode * next;
While (1)
{
// Keep accessing the left subtree
While (current! = NULL)
{
// For the first access, access the node data, save the parent node address in the left domain, and continue to access the left subtree.
Visit (current );
Next = current-> left;
Current-> left = previous;
Previous = current;
Current = next;
}
 
// Trace back until the right subtree of a node has not been accessed
While (previous! = NULL & (int) previous-> left & 0x01 ))
{
// For the third access, the parent node address is now saved in the right domain. Clear the flag and restore the original right value to the parent node.
Previous-> left = (TreeNode *) (int) previous-> left & 0 xfffffffe );
Next = previous-> right;
Previous-> right = current;
Current = previous;
Previous = next;
}
 
If (previous = NULL) // The root node is accessed for the third time. The whole tree traversal ends and the loop is exited.
Break;
Else
{
// For the second access, the parent node address is now saved in the left field, marked,
// Restore the original value of the left field, save the parent node address in the right field, and then enter the right subtree.
Previous-> left = (TreeNode *) (int) previous-> left | 0x01 );
Next = (TreeNode *) (int) previous-> left & 0 xfffffffe );
Previous-> left = (TreeNode *) (int) previous-> left & 0x01) | (int) current );
Current = previous-> right;
Previous-> right = next;
}
}
}

# Pragma pack (4)
Struct TreeNode
{
Int val;
TreeNode * left;
TreeNode * right;
};

Void Visit (TreeNode * node)
{
Printf ("% d \ n", node-> val );
}

Void Traversal (TreeNode * root)
{
If (root = NULL)
Return;
TreeNode * previous = NULL;
TreeNode * current = root;
TreeNode * next;
While (1)
{
// Keep accessing the left subtree
While (current! = NULL)
{
// For the first access, access the node data, save the parent node address in the left domain, and continue to access the left subtree.
Visit (current );
Next = current-> left;
Current-> left = previous;
Previous = current;
Current = next;
}

// Trace back until the right subtree of a node has not been accessed
While (previous! = NULL & (int) previous-> left & 0x01 ))
{
// For the third access, the parent node address is now saved in the right domain. Clear the flag and restore the original right value to the parent node.
Previous-> left = (TreeNode *) (int) previous-> left & 0 xfffffffe );
Next = previous-> right;
Previous-> right = current;
Current = previous;
Previous = next;
}

If (previous = NULL) // The root node is accessed for the third time. The whole tree traversal ends and the loop is exited.
Break;
Else
{
// For the second access, the parent node address is now saved in the left field, marked,
// Restore the original value of the left field, save the parent node address in the right field, and then enter the right subtree.
Previous-> left = (TreeNode *) (int) previous-> left | 0x01 );
Next = (TreeNode *) (int) previous-> left & 0 xfffffffe );
Previous-> left = (TreeNode *) (int) previous-> left & 0x01) | (int) current );
Current = previous-> right;
Previous-> right = next;
}
}
}

 

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.