Non-recursive traversal of binary tree
The recursive traversal of the binary tree is briefly introduced in the last section, and this section introduces the implementation of recursive traversal of the two-fork tree, which mainly describes the non-recursive traversal implementation of the binary tree, and continues to cite the example of the previous section to illustrate the following.
I. First ORDER traversal
The order of access for binary tree First order traversal is: 根结点->左孩子->右孩子
. Simply put, for any one node, can be regarded as a root node, directly to its access, if the access is completed, the left child is not empty, you can see the left child again as a new root node, then go back to the beginning, access to the root node, access to the left child, if the left child is empty, access to its right child. For the general program, the recursive program to non-recursive program needs to introduce 栈
this data structure, can refer to the 2nd Chapter 1th stack of the basic definition and implementation, the process can be divided into three simple steps:
For any node T:
- Access the node T and put the node t into the stack;
- To determine whether the left child of the node T is empty, if not empty, the left child of the node t into the stack, and then Judge T's right child is empty, if not empty, the node T's right child into the stack, if the left child or right child is empty, the stack is accessed. It should be noted that the characteristics of the stack,
先进后出
so you need to first put the right child into the stack, and then the left child into the stack;
- End the access until the stack is empty.
The algorithm is described as follows:
void PreOrder(BiTNode* T){ SqStack S; InitStack(&S); BiTNode* p=T; Push(&S,p); while(IsEmptyStack(&S)!=0){ p=Pop(&S); printf("%c",p->data); if(p->rchild!=NULL){ Push(&S,p->rchild); } if(p->lchild!=NULL){ Push(&S,p->lchild); } }}
Two. Middle Sequence traversal
The sequence traversal in the binary tree is accessed in the order 左孩子->根结点->右孩子
. In a nutshell: Scan (not access) all left children of the root node and put them one by one on the stack, then stack up a node and *p
access it, scan the node's *p
right child, and then scan it into the stack with all the left children of the node's *p
right child as the root node, and one by one into the stack, Continue until the stack is empty. The process can be easily divided into three steps:
For any node T:
- First determine whether the node T is empty, if not empty, then put it into the stack, and then the pointer p points to the left child of T, and then continue to repeat the step until the node T is empty;
- After the first step can ensure that the top element of the stack must be the left child node of the two fork tree, and then out of the stack to access the node, and then determine whether the right child is empty, if not empty, then scan the right child's left child node, repeat the 1th step;
- End the access until the stack is empty.
The algorithm is described as follows:
void InOrder(BiTNode* T){ SqStack S; InitStack(&S); BiTNode* p=T; while(p||IsEmptyStack(&S)!=0){ if(p!=NULL){ Push(&S,p); p=p->lchild; }else{ p=Pop(&S); printf("%c",p->data); p=p->rchild; } }}
Three. Post-traversal
The sequence traversal in the binary tree is accessed in the order 左孩子->右孩子->根结点
. Because the sequence of non-recursive traversal of the binary tree is to first access the left child, then access the right child, and finally access the root node. So when using stacks to store nodes, you must distinguish between returning the root node from the left child or returning from the right child, you need to set a secondary pointer r to point to the most recently visited node. The process can be easily divided into three steps:
For any node T:
- First determine whether the root node is empty, if not empty, then continue into the stack until the leftmost left child node;
- Then take out the top node of the stack to determine whether the right child is empty, and the right child has not been visited, and then the right child into the stack, and then repeat the 1th, 2 steps;
- However, if the right child is empty, the stack is accessed and marked on that node.
The algorithm is described as follows:
void PostOrder(BiTNode* T){ SqStack S; InitStack(&S); BiTNode *p=T; BiTNode *r=NULL; while(p||IsEmptyStack(&S)!=0){ if(p!=NULL){ Push(&S,p); p=p->lchild; }else{ p=GetTop(&S); if(p->rchild!=NULL&&p->rchild!=r){ p=p->rchild; Push(&S,p); p=p->lchild; }else{ p=Pop(&S); printf("%c",p->data); r=p; p=NULL; } } }}
Four. Hierarchical traversal
The general two-fork tree-level traversal is top-down, from left to right. Simply to access the root node first, and then access its left child, right child, you can use the characteristics of the queue 先进先出
to achieve hierarchical traversal, you can refer to the 2nd Chapter 2nd section of the basic definition of the queue and implementation method, its processing can be easily divided into three steps:
For any node T:
- Access the node T and then queue the node T;
- Out of the team to visit the node, and then determine whether the left child and the right child is empty, if not empty, then separate it into the queue;
- If it is empty, the team will be able to visit;
void PostOrder(BiTNode* T){ SqStack S; InitStack(&S); BiTNode *p=T; BiTNode *r=NULL; while(p||IsEmptyStack(&S)!=0){ if(p!=NULL){ Push(&S,p); p=p->lchild; }else{ p=GetTop(&S); if(p->rchild!=NULL&&p->rchild!=r){ p=p->rchild; Push(&S,p); p=p->lchild; }else{ p=Pop(&S); printf("%c",p->data); r=p; p=NULL; } } }}
Specific code See attachment
Attachment
//ab#df## #C #e###include <stdio.h>#include <stdlib.h>#define MaxSizetypedef CharElemtype;/*-----------------------------------------*/typedef structbitnode{elemtype data;structBitnode *lchild, *rchild;} Bitnode, *bitree; bitnode* Createbitree (bitnode*);voidPreorder (bitnode*);voidInorder (bitnode*);voidPostorder (bitnode*);voidLevelorder (bitnode*);/*-----------------------------------------*/typedef structsqstack{bitnode* Data[maxsize];intTop;} Sqstack;voidInitstack (sqstack*);voidPush (sqstack*,bitnode*); bitnode* Pop (sqstack*); bitnode* GetTop (sqstack*);intIsemptystack (sqstack*);typedef structsqqueue{bitnode* Data[maxsize];intFront, Rear;} Sqqueue;voidInitqueue (sqqueue*);voidEnQueue (sqqueue*, bitnode*); bitnode* DeQueue (sqqueue*);intIsemptyqueue (sqqueue*);/*-----------------------------------------*/intMainintargcChar* argv[]) {Bitnode *t= (bitnode*)malloc(sizeof(Bitnode)); T=createbitree (T); Preorder (T);printf("\ n"); Inorder (T);printf("\ n"); Postorder (T);printf("\ n"); Levelorder (T);printf("\ n");return 0;}//Create two-fork treeBitree Createbitree (bitnode* T) {elemtype x;scanf("%c", &x);if(x==' # '){returnT }Else{t= (bitnode*)malloc(sizeof(Bitnode)); t->data=x; T->lchild=createbitree (T->lchild); T->rchild=createbitree (T->rchild); }returnT;}//First Order traversalvoidPreorder (bitnode* T) {sqstack S; Initstack (&s); bitnode* p=t; Push (&S,P); while(Isemptystack (&s)! =0) {P=pop (&s);printf("%c", P->data);if(P->rchild!=null) {Push (&s,p->rchild); }if(P->lchild!=null) {Push (&s,p->lchild); } }}//Middle sequence traversalvoidInorder (bitnode* T) {sqstack S; Initstack (&s); bitnode* p=t; while(p| | Isemptystack (&s)! =0){if(P!=null) {Push (&s,p); p=p->lchild; }Else{P=pop (&s);printf("%c", P->data); p=p->rchild; } }}// post-traversalvoidPostorder (bitnode* T) {sqstack S; Initstack (&s); Bitnode *p=t; Bitnode *r=null; while(p| | Isemptystack (&s)! =0){if(P!=null) {Push (&s,p); p=p->lchild; }Else{p=gettop (&s);if(P->RCHILD!=NULL&&P->RCHILD!=R) {p=p->rchild; Push (&S,P); p=p->lchild; }Else{P=pop (&s);printf("%c", P->data); R=p; P=null; } } }}//Hierarchical TraversalvoidLevelorder (bitnode* T) {sqqueue Q; Initqueue (&Q); Bitnode *p=t; EnQueue (&Q,P); while(Isemptyqueue (&q)! =0) {p=dequeue (&q);printf("%c", P->data);if(P->lchild!=null) {EnQueue (&q,p->lchild); }if(P->rchild!=null) {EnQueue (&q,p->rchild); } }}/*-----------------------------------------*/voidInitstack (sqstack* S) {s->top=-1;}voidPush (sqstack* S, bitnode* T) {if(s->top==maxsize-1){return; } s->data[++s->top]=t;} bitnode* Pop (sqstack* S) {if(s->top==-1){returnNULL; }returns->data[s->top--];} bitnode* GetTop (sqstack* S) {if(s->top==-1){returnNULL; }returnS->data[s->top];}intIsemptystack (sqstack* S) {if(s->top==-1){return 0; }return-1;}/*-----------------------------------------*/voidInitqueue (sqqueue* Q) {q->front=0; Q->rear=0;}voidEnQueue (sqqueue* Q, bitnode* T) {if((q->rear+1) {%maxsize==q->front) {return; } q->data[q->rear++]=t;} bitnode* DeQueue (sqqueue* Q) {if(q->front==q->rear) {returnNULL; }returnq->data[q->front++];}intIsemptyqueue (sqqueue* Q) {if(q->front==q->rear) {return 0; }return-1;}
4th Chapter 3rd The basic operation of the binary tree (non-recursive implementation)