#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct node
{
char data;
struct node* lchild;
struct node* rchild;
}*bitree,bitnode;
typedef struct qstack
{
bitree *base;//存储bitree指针的数组,所以类型是bitree,因为存储的是一级指针的地址,所以该指针数组为二级指针数组
int top;
int size;
}qstack;
void init(qstack &s)
{
s.base=(bitree*)malloc(100*sizeof(bitree));
s.top=0;
}
bool empty(qstack &s)
{
if(s.top==0)
return true;
else
return false;
}
void push(qstack &s,bitree e)//注意入栈的时候,是e指针的地址
{
s.base[s.top]=e;
s.top++;
}
void pop(qstack &s)
{
s.top--;
}
bitree gettop(qstack &s)//返回栈顶元素也应该是bitree即返回指针
{
return s.base[s.top-1];
}
void traverse(qstack &s)
{
int i;
for(i=0;i<s.top;i++)
{
cout<<s.base[i];
}
}
void create(bitree &bt)//先序次序创建二叉树
{
char data;
cin>>data;
if(data == '#')
{
bt=NULL;
}
else
{
bt=(bitree)malloc(sizeof(bitnode));
bt->data=data;
create(bt->lchild);
create(bt->rchild);
}
}
void pretraverse(bitree bt)//先序遍历递归版
{
if(bt!=NULL)
{
cout<<bt->data;
pretraverse(bt->lchild);
pretraverse(bt->rchild);
}
}
void ontraverse(bitree bt)//中序遍历递归版
{
if(bt!=NULL)
{
ontraverse(bt->lchild);
cout<<bt->data;
ontraverse(bt->rchild);
}
}
void postraverse(bitree bt)//后序遍历递归版
{
if(bt!=NULL) //记住要加上这个判断语句,因为如果是左孩子活右孩子为空,则不能输出data
{
postraverse(bt->lchild);
postraverse(bt->rchild);
cout<<bt->data;
}
}
void pretraverse_(bitree bt)//先序遍历非递归版
{
bitree &p=bt;
qstack s;
init(s);
while(!empty(s) || p!=NULL)
{
while(p!=NULL)
{
cout<<p->data;
push(s,p);
p=p->lchild;
}
if(!empty(s))
{
p=gettop(s);
pop(s);
p=p->rchild;
}
}
}
void ontraverse_(bitree bt)//中序遍历非递归版
{
bitree &p=bt;
qstack s;
init(s);
while(!empty(s) || p!=NULL)
{
while(p!=NULL)
{
push(s,p);//结点入栈
p=p->lchild;//一直往左孩子方向进行直到没有左孩子的时候跳出
}
if(!empty(s))
{
p=gettop(s);//如果不加上这个,当p从上一个while跳出时为空,不能输出data
cout<<p->data;//如果是左孩子则输出,左孩子出栈,左孩子的右孩子是空,p变成根结点
pop(s);
p=p->rchild;
}
}
}
void postraverse_(bitree bt)//后序非递归遍历
{
char k;
qstack s;
init(s);
bitree cur;
bitree pre=NULL;
push(s,bt);
while(!empty(s))
{
cur=gettop(s);
if(((cur->lchild == NULL) && (cur->rchild == NULL)) || (pre!=NULL && ((pre==(cur->lchild) || pre==(cur->rchild)))))
{
k=cur->data;
cout<<cur->data;
pop(s);
pre=cur;
}
else
{
if(cur->rchild!=NULL)//此处应该注意,先是右孩子入栈,然后才是左孩子,因为后序遍历的最开始是左孩子,所以应该往左孩子的方向进行判断
push(s,cur->rchild);//但是如果先放入左孩子入栈,在放入右孩子入栈,则取栈顶的时候,是右孩子,然后方向就变成了向右孩子的方向所以
if(cur->lchild!=NULL)//应该右孩子先入栈左孩子后入栈
push(s,cur->lchild);
}
}
}
int main()
{
bitree bt;
create(bt);
postraverse_(bt);
}
二叉树的各种遍历
最新推荐文章于 2024-03-31 14:28:55 发布