二叉树的各种遍历(递归,非递归,层次)

如有错误,欢迎大家指出来

定义的栈,队列,二叉树结构体
typedef struct node{
Bitree tri;
struct node *next;
}lnode;
typedef struct{
lnode *front,*rear;
}linkqueue;//链队列
typedef struct liknode{
Bitree tre;
struct liknode *next;
}stacknode;
typedef struct stac{
stacknode *top;
}linkstack;//链栈
typedef struct bi{
int num;
struct bi *lchild,*rchild;
}Binode,*Bitree;//二叉树节点
#include"tree.h"
#include<stdio.h>
#include"queue.h"
#include<stdlib.h>
#include"stack.h"
void visit(Bitree p)
{
    printf("%d ",p->num);
}
Bitree create(Bitree q)
{
    int n;
    printf("input :");
    scanf("%d",&n);
    if(n==-1) q=NULL;//输入为-1时,表示节点为空,否则开辟空间,增加节点
    else {
         q=(Bitree)malloc(sizeof(Binode));
         q->num=n;
        q->lchild=create(q->lchild);
        q->rchild=create(q->rchild);//利用递归先序遍历创建法!
         }
       return q;
}
void preorder(Bitree p)//递归先序
{
if(p!=NULL)
 {
     printf("%d ",p->num);
     preorder( p->lchild);
     preorder(p->rchild);
     }
}
void inorder(Bitree p)//递归中序
{
    if(p!=NULL){
        inorder(p->lchild);
        printf("%d ",p->num);
        inorder(p->rchild);
               }
}
void postorder(Bitree p)//递归后序
{
    if(p!=NULL)
    {
         inorder(p->lchild);
        inorder(p->rchild);
        printf("%d ",p->num);
    }
}
void  levelorder(Bitree p)//队列实现层次遍历
{
    linkqueue *q;
    q=(linkqueue *)malloc(sizeof(linkqueue));
    iniqueue(q);
    Bitree t=p;
    enqueue(q,t);
    while(!quempty(q))
    {   t=dequeue(q);
      printf("%d ",t->num);
       if(t->lchild!=NULL) enqueue(q,t->lchild);
       if(t->rchild!=NULL) enqueue(q,t->rchild);
    }//首先,根节点进队,非空,输出根节点,发现根节点有左右节点,把他们入队,又回到while,非空,
}  //根节点的左孩子出队,发现左孩子还有孩子,将之入队,根节点的右孩子出队,发现它有孩子就把孩子入队
//依次下去直到queempty退出while
void  inordertraver(Bitree p)//非递归中序.栈实现
{
    linkstack *r;
    r=(linkstack*)malloc(sizeof(linkstack));
    inistack(r);//构建好链栈r
    Bitree t;
    t=p;//p作为指向树的根节点指针,不要改变,声明一个指针t=p来实现遍历
    while(t||!stackempty(r))//t非空或者栈非空
    {
        if(t) {push(r,t);t=t->lchild;}//若t不为空,入栈,
        else {                        //t为空,此时栈顶元素为t父节点,出栈,且使t指向父节点
              t=pop(r); visit(t);
              t=t->rchild;//t指向它的右孩子t=t->rchild
                }
    }//若右孩子t为空,栈不为空,再次进入while,pop出最近进入的一个节点,即此时t的父节点,
} //若右孩子不为空,则进入if,依次循环下去,直到while条件不满足
void  preordertraver(Bitree p)//非递归先序.栈
{
  linkstack *r;
  r=(linkstack*)malloc(sizeof(linkstack));
  inistack(r);
  Bitree t;
  t=p;
  while(t||!stackempty(r))
  {
      if(t){push(r,t);t=gettop(r);visit(t);t=t->lchild;}//类似上面,不过在push之后就要输出push的值
      else {                         //但是不能pop出去,如果pop出去了,只能遍历每行最左边的节点
             t=pop(r);//找到一个节点,它为空,t等于出栈元素(即t的父节点!)
             t=t->rchild;//让t指向它的右孩子,为空时继续进入else,pop栈顶,不为空时进入if,再做刚才的判断
           }
  }
}
void postordertraver(Bitree p)//后序非递归遍历.栈
{
    linkstack *r;
    r=(linkstack*)malloc(sizeof(linkstack));
    inistack(r);
    Bitree t,l;
    t=p;l=NULL;
   while(t){push(r,t);t=t->lchild;}//最左边节点均入栈!最终push的是二叉树最左边的节点
   while(!stackempty(r))
   {
       t=gettop(r);//获得栈顶节点
     if(!t->rchild||l==t->rchild){l=pop(r);visit(l);}//如果t右孩子节点为空或已被访问,则pop掉,l记录位置
     else {                                       //l总是所在判断的节点的上一个被删除的节点
            t=t->rchild;//t右节点不为空且右节点未被访问,t=rchild;
            while(t){push(r,t);t=t->lchild;}//如果更新后的节点不为空,则左孩子while入栈,只到没有左孩子节点
            }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值