Implementation of Non-recursive algorithms for Binary Tree first-order traversal

Source: Internet
Author: User

In the previous article, we talked about the recursive traversal algorithm of a binary tree (the improvement of the first root (First Order) traversal of a binary tree). This article mainly describes the non-recursive algorithm of a binary tree and uses the stack structure.

The non-recursive algorithm obtained by root traversal is summarized as follows:

1) in the stack, the first node is the first node into the stack, and then visit this node

2) while, cyclically traverse the current node until the left child has no node

3) if the right child of the node is true, transfer in 1) continue to traverse, otherwise exit the current node and transfer to the parent node to traverse and transfer in 1)

First, let's look at the algorithms that conform to this idea:

Copy codeThe Code is as follows:
Int PreOrderTraverseNonRecursiveEx (const BiTree & T, int (* VisitNode) (TElemType data ))
{
If (T = NULL)
{
Return-1;
}

BiTNode * pBiNode = T;
SqStack S;
InitStack (& S );
Push (& S, (SElemType) T );

While (! IsStackEmpty (S ))
{
While (pBiNode)
{
VisitNode (pBiNode-> data );
If (pBiNode! = T)
{
Push (& S, (SElemType) pBiNode );
}
PBiNode = pBiNode-> lchild;
}
If (pBiNode = NULL)
{
Pop (& S, (SElemType *) & pBiNode );
}
If (pBiNode-> rchild = NULL)
{
Pop (& S, (SElemType *) & pBiNode); // If the stack is empty at this time, the problem occurs.
}
PBiNode = pBiNode-> rchild;
}

Return 0;
}

Note: 1) the stack structure is used here. For details, refer to the stack stored in the sequential structure above.

2) When saving the node, I saved the pointer, that is, the node address, and changed it to int-type storage. In pop, the pointer is used, therefore, we use & pBiNode instead of pBiNode. We recommend that you think about the usage of pointers on your own. The best thing to understand is BiTNode * pBiNode. The definition of BiTree pBiNode is quite understandable.


The above algorithm is actually incorrect! Why? Here I checked for a long time. During this period, there were still infinite loops, and the left subtree was not displayed after exiting from the left subtree. Finally, I modified the first while judgment condition. Why? If the stack is empty but the right subtree still exists after pop, the stack will not be able to continue. I did not perform much verification after writing it, and I will explain it later, the null pointer is not pushed here. Let's take a look at the example of pushing a null pointer. It is only pushed into the stack when the left subtree is empty, as shown below:

Copy codeThe Code is as follows:
Int PreOrderTraverseNonRecursive (const BiTree & T, int (* VisitNode) (TElemType data ))
{
If (T = NULL)
{
Return-1;
}

BiTNode * pBiNode = T;
SqStack S;
InitStack (& S );
Push (& S, (SElemType) T );

While (! IsStackEmpty (S ))
{
GetTop (S, (SElemType *) & pBiNode );
While (pBiNode)
{
VisitNode (pBiNode-> data );
PBiNode = pBiNode-> lchild;
Push (& S, (SElemType) pBiNode );
}
If (pBiNode = NULL)
{
Pop (& S, (SElemType *) & pBiNode );
}
If (! IsStackEmpty (S ))
{
Pop (& S, (SElemType *) & pBiNode );
PBiNode = pBiNode-> rchild;
Push (& S, (SElemType) pBiNode );
}
}

Return 0;
}

This is the case here. First press the root node, and then judge whether the left subtree is empty. If it is not empty, press the node into the stack. Otherwise, after exiting the while loop, the NULL node is terminated out of the stack, then judge whether the current stack is empty. If it is not empty, it gets the parent node from the stack and then judges the right child, presses it into the right child node, and then judges whether the left child of the right child tree is empty, continue the loop.

There are two waste points: one is to press the empty child node into the stack, and the other is to frequently use GetTop to obtain the top element of the stack.


Here we will return and look at the algorithm we designed at the beginning. There is no such thing as a NULL pointer or a NULL child node, but the output is not complete. Here we think we can add it when judging the stack, if the current node is NULL, it will not show the embarrassment of exiting the left subtree node and not displaying the right subtree node, as shown below:

Copy codeThe Code is as follows:
// Non-recursive first-order traversal of Binary Trees
Int PreOrderTraverseNonRecursiveEx (const BiTree & T,
Int (* VisitNode) (TElemType data ))
{
If (T = NULL)
{
Return-1;
}

BiTNode * pBiNode = T;
SqStack S;
InitStack (& S );
Push (& S, (SElemType) T );

While (! IsStackEmpty (S) | pBiNode) // you can modify this statement.
{
While (pBiNode)
{
VisitNode (pBiNode-> data );
If (pBiNode! = T)
{
Push (& S, (SElemType) pBiNode );
}
PBiNode = pBiNode-> lchild;
}
If (pBiNode = NULL)
{
Pop (& S, (SElemType *) & pBiNode );
}
If (pBiNode-> rchild = NULL)
{
Pop (& S, (SElemType *) & pBiNode); // If the stack is empty at this time, the problem occurs.
}
PBiNode = pBiNode-> rchild;
}
Return 0;
}

After this is added to the first while loop, the test case is similar to the binary tree sequential traversal. The following is an example of a binary tree in the previous test section:

The input data is still 12 34 0 0 78 0. The test result is as follows:


--- BiTree ---
Please Enter BiTree Node data:
12
Please Enter BiTree Node data:
34
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
78
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
12 34 78

This is not enough for testing. Let's look at the following binary tree.

The input data is 12 34 24 0 0 50 0 78 37 0 0 0 0. The test result is as follows:

--- BiTree ---
Please Enter BiTree Node data:
12
Please Enter BiTree Node data:
34
Please Enter BiTree Node data:
24
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
50
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
78
Please Enter BiTree Node data:
37
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
Please Enter BiTree Node data:
0
12 34 24 50 78 37

It can be seen from the first-order traversal that the algorithms are correct. In addition, these algorithms are not only for first-order traversal. If you want to change to the middle or back-order, you only need to remove visit from the above algorithm and then add it to the appropriate location.

Related Article

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.