递归实现
先序遍历
![](https://img-blog.csdnimg.cn/direct/777cb5ceb8d94853b291a3c349729bc3.png)
代码实现
![](https://img-blog.csdnimg.cn/direct/84e992ab86934624915e84d11802aaaf.png)
存储状态
![](https://img-blog.csdnimg.cn/direct/067c86b0e7164e6198e18c258447a3e5.png)
中序遍历
![](https://img-blog.csdnimg.cn/direct/f3811f0b5dca4088a468e20afb2111c9.png)
![](https://img-blog.csdnimg.cn/direct/0dd84059373b4615acdc58463406ef4c.png)
后序遍历
![](https://img-blog.csdnimg.cn/direct/4fb8fc8f03c44b748d5b1d23c370daa9.png)
![](https://img-blog.csdnimg.cn/direct/d4e2511c11324e3a8caa1cf718112da9.png)
算法分析
实质
![](https://img-blog.csdnimg.cn/direct/3c090c86a1684406988f379672a11ec6.png)
复杂度
![](https://img-blog.csdnimg.cn/direct/451a880425af4f0c913dd969be92dca0.png)
非递归算法实现
![](https://img-blog.csdnimg.cn/direct/c7bbda4add6c47e6a3c816553e72033c.png)
中序遍历
![](https://img-blog.csdnimg.cn/direct/f979f8285dbc4cbb9a8250f02e3cd144.png)
层次遍历
原理
![](https://img-blog.csdnimg.cn/direct/0a76c7d03c2a45ad8b3ae618a6fd42dc.png)
![](https://img-blog.csdnimg.cn/direct/b0cb238656b54b67957efd9124861f59.png)
实现
![](https://img-blog.csdnimg.cn/direct/55416b61e0f44d27b11a74be6fde4731.png)
![](https://img-blog.csdnimg.cn/direct/4761d7b7237c4c93b111b498d14df4ef.png)
代码整合:
//二叉链式存储 :数据域+左右指针域
typedef struct node{
int data;
node *lchild,*rchild;//
}bitnode,*bitree;
//bitree bt;
//递归遍历:本质都是一个访问路径,只不过输出时机不同而已
//先序遍历
1.非空判断
2.根-访问 左右-不断递归调用自身遍历左右子树
void preoder(bitree bt){
bitnode *p=bt;//不要直接对树进行振作,最好定义一个新指针来振作
if(p!=NULL){
cout<<p->data<<endl;
preoder(p->lchild);
preoder(p->rchild);
}
}
//中序遍历
1.非空判断
2. 左 根-访问 右-不断递归调用自身遍历左右子树
void inoder(bitree bt){
bitnode *p=bt;//不要直接对树进行振作,最好定义一个新指针来振作
if(p!=NULL){
inoder(p->lchild);
cout<<p->data<<endl;
inoder(p->rchild);
}
}
//后序遍历
1.非空判断
2. 左右-不断递归调用自身遍历左右子树 根-访问
void postoder(bitree bt){
bitnode *p=bt;//不要直接对树进行振作,最好定义一个新指针来振作
if(p!=NULL){
postoder(p->lchild);
postoder(p->rchild);
cout<<p->data<<endl;
}
}
//非递归遍历:通过栈实现
//先序遍历
1.初始化栈
2.树与栈非空时:
树非空,访问,入栈,不断遍历左子树
树为空,栈非空,出栈,不断遍历右子树
void preoder(bitree bt){
initial(s);
bitnode *q=bt,*q;
while(q||!empty(s)){
if(q){
cout<<q->data<<endl;
push(s,q);
q=q->lchild;
}else{
pop(s,q);
p=q->rchild;
}
}
}
//中序遍历
1.初始化栈
2.树与栈非空时:
判断,若树非空,不断让元素入栈,遍历左子树
当树为空时,此时栈非空,出栈,不断访问元素,遍历右子树
void inorder(bitree bt){
initial(s);
bitnode *p=bt,*q;//q-装出栈元素
while(p||!empty(s)){
if(p){
push(s,p);
p=p->lchild;
}else{
pop(s,q);
cout<<q->data<<endl;
p=q->rchild;
}
}
}
//后序遍历:
1.初始化栈
2.树与栈非空时:
判断,若树非空,不断让元素入栈,遍历左子树
当树为空时,此时栈非空,取栈顶元素,
判断是否右子树是否为空或是否被访问,不为空且未被访问,不断遍历右子树,
否则出栈,访问,记录访问结点出栈,不断访问元素,遍历右子树
void postoder(bitree bt){
initial(s);
bitnode *p=bt,*q;
while(p||!empty(s)){
if(p){
push(p);
p=p->lchild;
} else{
getTop(s,p);
if(p->rchild==NULL||p->rchild==q)
{
pop(s,p);
cout<<p->data<<endl;
q=p;
p=NULL;
}else p=p->rchild;
}
}
}
//层次遍历:通过队列实现
typedef struct node {
int data[maxn];
int front,rear;
}squeue;
void layer(bitree t){
squeue *q;//装二叉树
bitnode *p;
init(q);//初始化
enqueue(q,t);//二叉树入队
while(!q.empty()){
dequeue(q,p);//出队
cout<<p->data<<endl;
//非空入队
if(p->lchild) enqueue(q,p->lchild);
if(p->rchild) enqueue(q,p->rchild);
}
}