Non-recursive implementation of several traversal algorithms for binary tree

Source: Internet
Author: User

Non-recursive implementation of binary tree traversal

As opposed to recursive traversal of binary tree, non-recursive traversal appears to be much more complicated, but the benefit is that the time efficiency of the algorithm is improved. The following is a summary of the process of learning non-recursive traversal binary tree algorithm

For the sake of understanding, this paper takes the two-fork tree as an example to analyze the realization process of three kinds of traversal ways of binary tree.

I. Non-recursive implementation of the pre-sequence traversal of a two-fork tree

Without recursion, we need to use the data structure of the stack we learned before to implement the two-fork tree's pre-order traversal. According to the definition of the pre-order traversal, the root node is accessed first, then the left subtree is accessed, and the right subtree is accessed finally. To declare a pointer to a node pcur, we can first access the root node, then let the root node into the stack, and let the Pcur on the left sub-tree to move until the pcur is empty, the stack top element out of the stack, so that pcur on the top of the stack on the right subtree of the tree to continue to move

Described in natural language as:
For either node p,
1) Output node p, then put it into the stack, and then see if the left child of P is empty;
2) If P's left child is not empty, then P's left child is the current node, repeat 1) operation;
3) If the left child of P is empty, the top node of the stack is out of the stack, but not output, and the right child of the stack node is placed as the current node to see if it is empty;
4) If not empty, then cycle to 1) operation;
5) If it is empty, then continue out of the stack, but not output, at the same time the right child of the stack node is set to the current node, see if it is empty, repeat 4) and 5) operation;
6) until the current node p is null and the stack is empty, the traversal ends.

The following is a detailed analysis of the non-recursive implementation process for its first sequence traversal:
First, starting from root node A, according to Action 1), output A, and put it into the stack, because A's left child is not empty, according to Operation 2), B is the current node, and then according to Operation 1), will b output, and put it into the stack, because B's left child is not empty, according to Operation 2), D is the current node, and then according to Operation 1), Output d, and put it into the stack, when the output sequence is abd;
Because the left child of D is empty, according to Operation 3), stack top node D is out of the stack, but not output, and its right child is placed as the current node;
Because the right child of D is empty, according to Operation 5), continue to stack top Node B out of the stack, but do not output, and put its right child as the current node;
Because B's right child e is not empty, according to Operation 1), output e, and put it into the stack, at this time the output sequence is: Abde;
Because the left child of E is empty, according to Operation 3), the stack top node E is out of the stack, but does not output, and its right child is placed as the current node;
Because the right child of E is empty, according to Operation 5), continue to stack top node A out of the stack, but not output, and its right child is the current node;
Since A's right child C is not empty, according to Operation 1), output C, and put it into the stack, at this time the output sequence is: Abdec;
Since A's left child F is not empty, according to Operation 2), the F is set to the current node, and then according to Operation 1), output F, and put it into the stack, at this time the output sequence is: ABDECF;
Since the left child of f is empty, according to Operation 3, the top node F of the stack is out of stack, but not output, and the right child is placed as the current node;
Because F's right child is empty, according to Operation 5), continue to stack top element c out of the stack, but do not output, and put its right child as the current node;
At this point the stack is empty, and C's right child is null, so the traversal ends.

The code is as follows:

Status NRPreorder(BiTree T){BiTree stack[MAXSIZE],pCur=T;int top=-1;/*pCur不为空或栈不为空时循环*/while(pCur||top>-1){    Visit(pCur->data);/*打印当前节点*/    top++;    stack[top]=pCur;/*当前节点进栈*/    pCur=pCur->Lchild;/*在左子树上移动*/    /*若左子树为空,则让栈顶元素出栈,并在右子树上寻找直到pCur不为空*/    while(!pCur&&top>-1){        pCur=stack[top];        top--;        pCur=pCur->Rchild;    }}return OK;

}

Two. Non-recursive implementation of sequential traversal

According to the definition of the middle sequence traversal, the left subtree is accessed first, then the root node is accessed, and the right subtree is accessed finally. It is still possible to traverse with the stack. First declare pointer pcur point to the current node, if the current node has left dial hand tree, then the current node into the stack, if there is no left subtree, then print the current node, pcur the pointer into the right subtree, if there is no right subtree, then the stack top elements out of the stack, until the top of the stack is right subtree.

For either node p,
1) If the left child of P is not empty, then P is put into the stack and the left child of P is placed as the current node, then the same processing is done for the current node;
2) If the left child of P is empty, then the P node is output, then the right child of P is placed as the current node to see if it is empty;
3) If not empty, then repeat 1) and 2) operation;
4) If it is empty, then execute the stack operation, output stack top node, and the right child of the node that is out of the stack as the current node, see whether it is empty, repeat 3) and 4) operation;
5) until the current node p is null and the stack is empty, the traversal ends.

The following example analyzes the non-recursive implementation of the sequential traversal in detail:
First, starting from the root node A, the left child of a is not empty, according to Operation 1) A into the stack, then the B is the current node, B's left child is not empty, according to Operation 1), the B also into the stack, and then the D is the current node, because D is empty, according to Operation 2), Output D
Since D's right child is also empty, according to Operation 4), perform a stack operation, the stack top node B out of the stack, and the B is the current node, at this time the output sequence is db;
Because B's right child is not empty, according to Operation 3), its right child e is the current node, because E's left child is empty, according to Operation 1), output E, at this time the output sequence is DBE;
Because the right child of E is empty, according to Operation 4), perform a stack operation, stack top Node A out of the stack, and node A as the current node, at this time the output sequence is dbea;
The stack is empty at this time, however, the right child of Node A is not NULL, continue to execute, because A's right child is not empty, according to Operation 3), the right child C is the current node, because C's left child is not empty, according to Operation 1), c into the stack, its left child F is the current node, because F's left child is empty, According to Operation 2), output F, at this time the output sequence is: dbeaf;
Because F's right child is also empty, according to Operation 4), perform a stack operation, the stack top element c out of the stack, and set it as the current node, at this time the output sequence is: DBEAFC;
Because the right child of C is null, and at this time the stack is empty, according to Operation 5), the traversal ends.

The code is as follows:

Status NRInorder(BiTree T){BiTree stack[MAXSIZE],pCur=T;int top=-1;while(pCur||top>-1){    if(pCur->Lchild){        /*如果当前节点有左子树,则入栈*/         top++;        stack[top]=pCur;        pCur=pCur->Lchild;    }     else{        Visit(pCur->data);/*无左子树,直接访问当前节点*/        pCur=pCur->Rchild;/*进入右子树继续访问*/        /*无右子树,则栈顶元素出栈并打印*/        while(!pCur&&top>-1){            pCur=stack[top];            top--;            Visit(pCur->data);            pCur=pCur->Rchild;        }    }}

}

Three. Non-recursive implementation of post-post traversal

According to the definition of subsequent traversal, the first one accesses its left subtree, accesses its right subtree, and finally accesses its root node, and still implements the stack, declaring two pointers pre,pcur. The pcur is used to point to the current node, and the pre is used to point to the visited node.
First let the root node into the stack, when the stack is not empty, Pcur point to the top of the stack, if the top element of the stack no left or right subtree has been output, then directly print the current node, while the stack top elements out of the stack, so that pre=pcur. If this is not the case, then the right subtree of the current node, the left subtree into the stack in turn.

According to the order of sequential traversal, first access to the left subtree, and then access to the right subtree, and then access the root node, and for each subtree, and in the same order of access to traverse, the order of sequential traversal is: DEBFCA. The non-recursive implementation of post-order traversal is relatively difficult, to ensure that the root node in the Saozi right subtree is accessed before access, the idea is as follows:
for any node p,
1) the node p into the stack first;
2) If p does not exist left child and right child, or p exists left child or right child, But the left and right children have been exported, you can directly output node p, and put it out of the stack, the stack node p is marked as the last output node, and then the stack top node is set to the current node,
3) if the condition in 2), then the right child of P and left child in turn into the stack, the current node is reset to the top node, Then repeat Operation 2),
4) until the stack is empty, and the traversal ends.

The following is an example of a detailed analysis of the non-recursive implementation of its post-operation traversal:
First, set two pointers: The cur pointer points to the node that is currently being accessed, it points to the top node of the stack, resets it to the top of the stack after each node is out of the stack, and the pre node points to the previous access node;
Cur first point to the root node a,pre is set to null first, because a exists left child and right child, according to Operation 3), the right child C into the stack, and then left child B into the stack, cur to point to the top node of the stack B;
Since B also has left child and right child, according to Operation 3), E, D into the stack, cur to the top node of the stack D;
Since D has no left child, and no right child, according to Operation 2), directly output D, and put it out of the stack, the pre point to D,cur point to the top of the stack E, at this time the output sequence is: D;
Since e also has no left and right children, according to Operation 2), output E, and put it out of the stack, the pre point to e,cur points to the top node B, at this time the output sequence is: DE;
Because B's left and right children have been output, that satisfies the condition pre==cur->lchild or pre==cur->rchild, according to Operation 2), output B, and put it out of the stack, the pre point b,cur to the top node of the stack C, when the output sequence is: DEB;
Because C has left child, according to Operation 3), put it into the stack, cur point to the top node of the stack F;
Since F does not have left and right children, according to Operation 2), output F, and put it out of the stack, the pre point F,cur point to the Stack top node C, at this time the output sequence is: DEBF;
Because C's left child has been output, that satisfies the pre==cur->lchild, according to Operation 2), output C, and put it out of the stack, the pre point to C,cur to the top node A, when the output sequence is: DEBFC;
As the left and right children of a have been output, according to Operation 2), output A, and put it out of the stack, at this time the output sequence is: DEBFCA;
At this point the stack is empty and the traversal ends.

The code is as follows:

Status NRPostorder(BiTree T){BiTree stack[MAXSIZE],pCur=T,pre=NULL;/*pre用于标记已访问过的节点*/int top=-1;stack[++top]=T;while(top>-1){/*栈不空时循环*/    pCur=stack[top];/*pCur始终指向栈顶*/    /*如果当前节点没有左右子树或者左右子树已经被访问过*/    if((!pCur->Lchild&&!pCur->Rchild)||(pre&&(pre==pCur->Lchild||pre==pCur->Rchild))){        Visit(pCur->data);/*输出当前节点的值*/        top--;/*当前节点出栈*/        pre=pCur;/*标记为已访问过的节点*/    }    /*不是上述情况,则当前节点左右子树分别进栈*/    else{        if(pCur->Lchild)           stack[++top]=pCur;        if(pCur->Rchild)           stack[++top]=pCur;    }}

}


Four. Sequence traversal of a two-fork tree

Because the binary tree has the hierarchy structure, it can traverse according to the sequence, consider the order problem, we adopt the queue realization. Queue from top to bottom, from left to right. The algorithm idea is to first let the root node queue, if the root node has left and right subtree, then let the left and right sub-tree queue, then let the team first element out of the team and print. Repeated until the queue is empty

Queue the root node of the tree first,

If the queue is not empty, enter the loop

{

The team first element out of the team, and output it;

If the first element of the team has a left child, the left child is enqueued;

If the first element of the team has a right child, the right child will be enqueued

The code is as follows:

Status LevelOrderTraverse(BiTree T){BiTree Queue[MAXSIZE],pCur=T;int front=-1,tail=-1;tail++;Queue[tail]=pCur;/*根节点入队*/while(front!=tail){    front++;    Visit(Queue[front]->data);/*打印队首节点*/    if(Queue[front]->Lchild){        tail++;        Queue[tail]=Queue[front]->Lchild;/*有左子树则左子树入队*/    }    if(Queue[front]->Rchild){        tail++;        Queue[tail]=Queue[front]->Rchild;    }}printf("\n");

}

In the process of writing this blog post, I have referred to these two blog posts:
http://blog.csdn.net/ns_code/article/details/13169703
http://blog.csdn.net/ns_code/article/details/12977901
Thank the author

Non-recursive implementation of several traversal algorithms for binary tree

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.