学习笔记非递归实现先后根遍历二叉树

Posted 周屹峰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习笔记非递归实现先后根遍历二叉树相关的知识,希望对你有一定的参考价值。

C语言代码:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 
  5 /*----方便看代码的定义----*/
  6 typedef int Status;
  7 #define OK 0
  8 #define NotOK 1
  9  
 10 #define STACK_INIT_SIZE 100       //栈空间初始分配量
 11 #define STACKINCREMENT 10         //栈空间分配增量 
 12 /*------------------------*/
 13 
 14 /*-----定义树结构-----*/
 15 typedef struct BiTree{
 16     char data;
 17     struct BiTree *Lchild;
 18     struct BiTree *Rchild;
 19 }BiTree,*TreeNode;
 20 /*--------------------*/
 21 
 22 /*-----输入字符串形式建立树(基于先根)-----*/
 23 /*例:输入 ABD#E##F##CG##HI###
 24     将会生成:            A
 25                        /     \\
 26                       B       C
 27                     /  \\    /  \\
 28                    D    F  G    H
 29                     \\          /
 30                      E        I           */
 31 TreeNode CreateBiTree(){
 32     char ch;
 33     TreeNode T;
 34     scanf("%c",&ch);
 35     if( ch == \'#\' ){
 36         T=NULL;
 37     }
 38     else{
 39         T = (TreeNode)malloc(sizeof(BiTree));
 40         T->data = ch;
 41         T->Lchild = CreateBiTree();
 42         T->Rchild = CreateBiTree();
 43     }
 44     return T;
 45 }
 46 /*-----------------------------------------*/
 47 
 48 /*------------------------建立栈------------------------*/
 49 typedef struct{
 50     TreeNode *base;     //在栈构造之前和销毁之后,base的值为NULL 
 51     TreeNode *top;      //栈顶指针 
 52     int stacksize;  //当前已分配的存储空间,以元素为单位 
 53 }Stack;
 54 
 55 Status InitStack(Stack &S){
 56     //构造一个空栈S 
 57     S.base = (TreeNode *)malloc(STACK_INIT_SIZE * sizeof(TreeNode));
 58     if(!S.base){
 59         exit(NotOK);  //存储分配失败 
 60     }
 61     S.top = S.base;
 62     S.stacksize = STACK_INIT_SIZE;
 63     return OK;
 64 }
 65 
 66 Status GetTop(Stack S, TreeNode &e){
 67     //若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回NotOK
 68     if(S.top == S.base){
 69         return NotOK;
 70     } 
 71     e = *(S.top-1);
 72     return OK;
 73 }
 74 
 75 Status Push(Stack &S, TreeNode e){
 76     //插入元素e为新的栈顶元素
 77     if(S.top - S.base >= S.stacksize){
 78         //栈满,追加存储空间
 79         S.base = (TreeNode *)realloc(S.base, (S.stacksize + STACKINCREMENT)*sizeof(TreeNode));
 80         if(!S.base){
 81             //存储分配失败 
 82             exit(NotOK);
 83         }
 84         S.top = S.base + S.stacksize;
 85         S.stacksize += STACKINCREMENT;
 86     }
 87     *S.top++ = e;
 88     return OK;
 89 }
 90 
 91 Status Pop(Stack &S, TreeNode &e){
 92     //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回NotOK
 93     if(S.top == S.base){
 94         return NotOK;
 95     } 
 96     e = * --S.top;
 97     return OK;
 98 }
 99 
100 bool StackIsEmpty(Stack &S){
101     //若栈为空,返回true;若栈非空,返回false
102     if(S.top == S.base){
103         return true;
104     } 
105     else{
106         return false;
107     }
108 }
109 /*------------------------------------------------------*/
110 
111 /*------非递归先根遍历------*/
112 Status PreOrderTraverse(TreeNode T){
113     if( T == NULL ){
114         return NotOK;
115     }
116     else{
117         printf("PreOrderTraverse:");
118         Stack TreeStack;
119         InitStack(TreeStack);
120         while( T!=NULL || !StackIsEmpty(TreeStack)){
121             while(T != NULL){
122                 printf("%c",T->data);
123                 Push(TreeStack,T);
124                 T = T->Lchild;
125             }
126             if(!StackIsEmpty(TreeStack)){
127                 Pop(TreeStack,T);
128                 T = T->Rchild;
129             }
130         }
131         printf("\\n");
132         return OK;
133     }
134 }
135 /*--------------------------*/
136 
137 /*------非递归后根遍历------*/
138 Status PostOrderTraverse(TreeNode T){
139     if( T == NULL ){
140         return NotOK;
141     }
142     else{
143         printf("PostOrderTraverse:");
144         Stack TreeStack;
145         TreeNode last;
146         TreeNode current;
147         Push(TreeStack,T); 
148         while(!StackIsEmpty(TreeStack)){
149             GetTop(TreeStack,current);
150             if((current->Lchild==NULL && current->Rchild==NULL)
151                 || (last != NULL && (last == current->Lchild
152                     || last == current->Rchild))){
153                 printf("%c",current->data);
154                 Pop(TreeStack, last);
155             }
156             else{
157                 if(current->Rchild != NULL){
158                     Push(TreeStack,current->Rchild);
159                 }
160                 if(current->Lchild != NULL){
161                     Push(TreeStack,current->Lchild);
162                 }
163             }
164         }
165         printf("\\n");
166         return OK;
167     }
168 }
169 /*--------------------------*/
170 
171 /*-----主函数-----*/
172 int main(){
173     TreeNode TreeRoot;
174     TreeRoot = CreateBiTree();
175     PreOrderTraverse(TreeRoot);
176     PostOrderTraverse(TreeRoot);
177 }
178 /*----------------*/

运行结果:

以上是关于学习笔记非递归实现先后根遍历二叉树的主要内容,如果未能解决你的问题,请参考以下文章

二叉树几种遍历算法的非递归实现

数据结构学习笔记——由遍历恢复二叉树以及非递归遍历二叉树

二叉树遍历的非递归实现

数据结构学习笔记——由遍历恢复二叉树以及非递归遍历二叉树

数据结构学习笔记——由遍历恢复二叉树以及非递归遍历二叉树

数据结构 - 二叉树遍历(递归,非递归)与构造