数据结构复习代码——非递归实现二叉树的遍历方法
1、非递归实现二叉树的遍历方法
1、非递归----后序遍历
#include<stdio.h> #include<assert.h> #include<malloc.h> #include"PostStack.h" #define ElemType char typedef struct BinTreeNode { ElemType data; struct BinTreeNode *leftchild; struct BinTreeNode *rightchild; }BinTreeNode; typedef struct BinTree { BinTreeNode *root; ElemType refvalue; }BinTree; //初始化 void InitBinTree(BinTree *bt,ElemType ref); //创建二叉树----非输入方式 创建方式可自行选择 void CreateBinTree_4(BinTree *bt,char *str); void CreateBinTree_4(BinTree *bt,BinTreeNode *&t,char *&str); //后续遍历 void postOrder_1(BinTree *bt); void postOrder_1(BinTreeNode *t); //////////////////////////////////////////////////////////// void InitBinTree(BinTree *bt,ElemType ref) { bt->root = NULL; bt->refvalue = ref; } void CreateBinTree_4(BinTree *bt,char *str) { CreateBinTree_4(bt,bt->root,str); } void CreateBinTree_4(BinTree *bt,BinTreeNode *&t,char *&str) { if(*str == bt->refvalue) t = NULL; else { t = (BinTreeNode*)malloc(sizeof(BinTreeNode)); assert(t != NULL); t->data = *str; CreateBinTree_4(bt,t->leftchild,++str); CreateBinTree_4(bt,t->rightchild,++str); } } //非递归---后序遍历二叉树 void postOrder_1(BinTree *bt) { postOrder_1(bt->root); } void postOrder_1(BinTreeNode *t) { if(t != NULL) { SeqStack st; InitStack(&st); StkNode sn; BinTreeNode *p; do{ while(t!=NULL) { sn.ptr = t; sn.tag = L; Push(&st,sn); t = t->leftchild; } bool flag = true; while(flag && !IsEmpty(&st)) { //sn = GetElem(&st); GetElem(&st,sn); Pop(&st); p = sn.ptr; switch(sn.tag) { case L: sn.tag = R; Push(&st,sn); flag = false; t = p->rightchild; break; case R: printf("%c ",p->data); break; } } }while(!IsEmpty(&st)); } } int main() { char *str = "ABC##DE##F##G#H##"; BinTree mytree; InitBinTree(&mytree,'#'); //CreateBinTree_3(&mytree); CreateBinTree_4(&mytree,str); postOrder_1(&mytree); printf("\n"); return 0; }
引用的PostStack.h头文件
#include<stdio.h> #include<malloc.h> #include<assert.h> #include<stdlib.h> struct BinTreeNode; typedef enum{L,R}Tag; typedef struct StkNode { BinTreeNode *ptr; Tag tag; }StkNode; #define ETStack StkNode #define STACK_INIT_SIZE 8 #define STACK_INC_SIZE 3 typedef struct SeqStack { ETStack *base; //每个节点的数据域 int capacity; //当前栈容量 int top; //栈顶指针 }SeqStack; //初始化栈 void InitStack(SeqStack *s) { s->base = (ETStack*)malloc(sizeof(ETStack)*STACK_INIT_SIZE); //为栈分配内存空间并赋值给首址 assert(s->base != NULL); //判断内存空间是否分配成功 s->capacity = STACK_INIT_SIZE; //栈最大空间初始化赋值给最大容量 s->top = 0; //栈顶指针赋值,指向0 } //辅助函数--判空操作 int IsEmpty(SeqStack *s) { if(s->top == 0) { return 1; }else{ return 0; } } //辅助函数--判满操作 int IsFull(SeqStack *s) { if(s->top == s->capacity) { return 1; }else{ return 0; } } //辅助函数--遍历栈 void Show(SeqStack *s) { for(int i=s->top-1;i>=0;i--) { printf("%d \n",s->base[i]); } } //辅助函数--获取栈顶元素 /* ETStack GetElem(SeqStack *s) { if(IsEmpty(s)){ printf("该栈已空!!"); //return 0; } int i = s->top; ETStack e = s->base[i-1]; return e; } */ int GetElem(SeqStack *s,ETStack &e) { if(IsEmpty(s)){ printf("该栈已空!!"); //return 0; } int i = s->top; e = s->base[i-1]; return 1; } //辅助函数--获取当前栈的长度 int Length(SeqStack *s){ //由于该栈定义时,栈顶指针是从0开始的,即当前栈的长度为栈顶指针所指 return s->top; } //辅助操作--增加栈内存空间 int Inc(SeqStack *s) { //使用realloc函数为s->base分配新的内存空间 ETStack *newbase = (ETStack*)realloc(s->base,sizeof(ETStack)*(s->capacity+STACK_INC_SIZE)); //此磁盘中已无内存空间可分配给次栈 if(newbase == NULL) { printf("内存空间已满!无法再次申请空间!"); return 0; } //将新分配的内存空间首址赋值给栈 s->base = newbase; //扩大该栈的最大容量 s->capacity += STACK_INC_SIZE; return 1; } //入栈操作 void Push(SeqStack *s,ETStack e) { if(IsFull(s)&& !Inc(s)) { printf("栈空间已满,不能入栈!!"); return; } s->base[s->top] = e; s->top++; } //出栈操作 void Pop(SeqStack *s) { if(IsEmpty(s)){ printf("栈已空,无元素可出栈!!"); return; } --s->top; //printf("出栈元素为:%d \n",s->base[s->top]); } //清除栈操作 void Clear(SeqStack *s) { //关于清除栈操作,只需将栈顶指针归零即可 //因为该栈内的相关元素已无实用价值,可以任意改变 s->top = 0; } //摧毁栈操作 void Destroy(SeqStack *s) { //摧毁栈,需要释放已分配该栈的内存空间 free(s->base); s->base=NULL; s->capacity = s->top = 0; }
2、前序和中序
//非递归----前序遍历 //本部分代码与上篇博客二叉树的定义以及相关实现相匹配(请勿与本篇代码融合运行) void preOrder_1(BinTree *bt) { preOrder_1(bt->root); } void preOrder_1(BinTreeNode *t) { if(t != NULL) { SeqStack st; InitStack(&st); BinTreeNode *p; Push(&st,t); while(!IsEmpty(&st)) { p = GetElem(&st); Pop(&st); printf("%c ",p->data); if(p->rightchild != NULL) Push(&st,p->rightchild); if(p->leftchild != NULL) Push(&st,p->leftchild); } } } void inOrder_1(BinTree *bt) { inOrder_1(bt->root); } void inOrder_1(BinTreeNode *t) { if(t != NULL) { SeqStack st; InitStack(&st); BinTreeNode *p; Push(&st,t); while(!IsEmpty(&st)) { while(t != NULL && t->leftchild != NULL) { Push(&st,t->leftchild); t = t->leftchild; } p = GetElem(&st); Pop(&st); printf("%c " ,p->data); if(p->rightchild != NULL) { t = p->rightchild; if(t != NULL) Push(&st,t); } } } }