二叉树非递归遍历(前、中、后)
参考博客:C语言实现二叉树的非递归遍历 (内含思想)
引用了参考博客的模板,替换了中序和后序遍历的函数,三个函数用了三种栈实现方法
由于是自己编写的,感觉比较繁琐(不适合笔试书写),底部给出了更简洁的版本
#include<stdlib.h> #include<stdio.h> #include<stack> #define N 20 using namespace std; typedef struct tree{ char ch; struct tree *lchild; struct tree *rchild; }BitTree; BitTree *CreateTree(){ BitTree *bt; char str; scanf("%c",&str); if(str=='#') return NULL; else{ bt=(BitTree *)malloc(sizeof(BitTree)); bt->ch=str; bt->lchild=CreateTree(); bt->rchild=CreateTree(); return bt; } } //压栈时,先压右子树 void PreOrder(BitTree *bt){ BitTree **s; BitTree *p; int top=-1; s=(BitTree **)malloc((N+1)*sizeof(BitTree *)); s[++top]=bt; while(top!=-1){ p=s[top--]; printf("%c ",p->ch); if(p->rchild) s[++top]=p->rchild; if(p->lchild) s[++top]=p->lchild; } free(s); } void InOrder(BitTree *bt){ stack<BitTree *> s; s.push(bt); BitTree *p=bt; while(p->lchild){ s.push(p->lchild); p=p->lchild; } while(!s.empty()){ p=s.top(); s.pop(); printf("%c ",p->ch); if(p->rchild){ s.push(p->rchild); p=p->rchild; while(p->lchild){ s.push(p->lchild); p=p->lchild; } } } } //增加flag标记判断是否遍历过右子树 void PostOrder(BitTree *bt){ BitTree* stack1[N]; BitTree* p=bt; int stack2[N], flag, top=-1; stack1[++top]=bt; stack2[top]=0; while(p->lchild){ stack1[++top]=p->lchild; stack2[top]=0; p=p->lchild; } while(top!=-1){ p=stack1[top]; flag=stack2[top--]; if(flag==0){ stack1[++top]=p; stack2[top]=1; if(p->rchild){ stack1[++top]=p->rchild; stack2[top]=0; p=p->rchild; while(p->lchild){ stack1[++top]=p->lchild; stack2[top]=0; p=p->lchild; } } } else{ printf("%c ",p->ch); } } } int main(){ printf("请以顺序输入二叉树(#表示该结点的子结点为空):\n"); BitTree *btr=CreateTree(); printf("前序遍历非递归实现:\n"); PreOrder(btr); printf("\n"); printf("中序遍历非递归实现:\n"); InOrder(btr); printf("\n"); printf("后序遍历非递归实现:\n"); PostOrder(btr); printf("\n"); return 0; } /* 输入样例:ABDG##H##E##C#F## A / \ B C / \ \ D E F / \ G H */
测试结果:
简洁版本: