二叉树的各种遍历算法

本文深入探讨了二叉树的前序遍历、中序遍历和后序遍历三种主要算法,详细解释了每种遍历方法的实现过程,并通过实例进行了演示。此外,还介绍了层次遍历和双向链表转换等扩展内容,帮助读者全面理解二叉树的遍历技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#include <stdlib.h>
#define MAX 20
//#define NULL 0
typedef  char TElemType;
typedef  int Status;
typedef struct BiTNode
{
    TElemType data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

typedef struct
{
    BiTree link;
    int flag;
}stacktype;

int count;
/*先序创建二叉树*/
void CreateBiTree(BiTree *T)
{
   char ch;
   ch=getchar();
   if (ch=='#') (*T)=NULL;     /*#代表空指针*/
    else 
    { 
        (*T)=(BiTree) malloc(sizeof(BiTNode));/*申请结点*/
        (*T)->data=ch; /*生成根结点*/
         count++;     //统计节点数量 
        CreateBiTree(&(*T)->lchild) ;        /*构造左子树*/
        CreateBiTree(&(*T)->rchild) ;        /*构造右子树*/
      }
}

/*先序输出二叉树*/
void PreOrder(BiTree T)
{   
    if (T)
    {  printf("%2c",T->data);    /*访问根结点,此处简化为输出根结点的数据值*/
       PreOrder(T->lchild);      /*先序遍历左子树*/
       PreOrder(T->rchild);      /*先序遍历右子树*/
     }
}

/*先序遍历的非递归实现*/
void NRPreOrder(BiTree bt)
{
    BiTree stack[MAX],p;
    int top;
    if(bt==NULL) return;
    top = 0;
    p = bt;
    while(!(p==NULL&&top==0))
    {
        while(p!=NULL)
        {
            printf("%2c",p->data);
            if(top<=MAX-1)
            {
                stack[top] = p;
                top++;
            }
            else 
             {
                printf("栈溢出\n");
                return;
             }
              p = p->lchild;
        }
        if(top<=0) return ;
        else 
        {
            top--;
            p = stack[top];
            p = p->rchild;
        }
    }
}


//中序遍历的递归算法 
void MidOrder(BiTree T)
{   
    if (T)
    { 
       MidOrder(T->lchild);      /*中序遍历左子树*/
       printf("%2c",T->data);    /*访问根结点,此处简化为输出根结点的数据值*/
       MidOrder(T->rchild);      /*中序遍历右子树*/
     }
}
//中序遍历的非递归算法 
void NRMidOrder(BiTree bt)
{
    BiTree stack[MAX],p;
    int top;
    if(bt==NULL) return;
    top = 0;
    p = bt;
    while(!(p==NULL&&top==0))
    {
        while(p!=NULL)
        {
            if(top<=MAX-1)
            {
                stack[top] = p;
                top++;
            }
            else 
             {
                printf("栈溢出\n");
                return;
             }
              p = p->lchild;
        }
        if(top<=0) return ;
        else 
        {
            top--;
            p = stack[top];
            printf("%2c",p->data);
            p = p->rchild;
        }
    }
}
//后序遍历递归算法 
void PostOrder(BiTree T)
{   
    if (T)
    { 
       PostOrder(T->lchild);      /*后序遍历左子树*/
       PostOrder(T->rchild);      /*后序遍历右子树*/
       printf("%2c",T->data);    /*访问根结点,此处简化为输出根结点的数据值*/
     }
}

//非递归后序遍历递归算法 
void NRPostOrder(BiTree bt)
{
    stacktype stack[MAX];
    BiTree p;
    int top,sign;
    if(bt == NULL)  return ;
    top = -1;
    p=bt;
    while(!(p==NULL&&top==-1))
    {
        if(p!=NULL)
        {
            top++;
            stack[top].link = p;
            stack[top].flag = 1;
            p = p->lchild;
        }
        else 
        {
            p = stack[top].link;
            sign=stack[top].flag;
            top--;
            if(sign==1)
            {
                top++;
                stack[top].link = p;
                stack[top].flag= 2;
                p=p->rchild;
            }
            else
            {
                printf("%2c",p->data);
                p=NULL;
            }
        }
    }
} 

/*层次遍历二叉树T,从第一层开始,每层从左到右*/
void LevelOrder(BiTree T)
{  
    BiTree Queue[MAX],b;  /*用一维数组表示队列,front和rear分别表示队首和队尾指针*/
   int front,rear;
   front=rear=0;
   if (T) /*若树非空*/
     { 
      Queue[rear++]=T;  /*根结点入队列*/
      while (front!=rear) /*当队列非空*/
    {   
       b=Queue[front++];   /*队首元素出队列,并访问这个结点*/
       printf("%2c",b->data);
       if (b->lchild!=NULL) Queue[rear++]=b->lchild; /*左子树非空,则入队列*/
       if (b->rchild!=NULL) Queue[rear++]=b->rchild; /*右子树非空,则入队列*/
       }
     }
}
/*求二叉树的深度*/
int depth(BiTree T)
{
   int dep1,dep2;
   if (T==NULL) return 0;
     else { 
         dep1=depth(T->lchild);
         dep2=depth(T->rchild);
         return dep1>dep2?dep1+1:dep2+1;
     }
 }

/*求二叉树深度的第二种方法*/ 
int depth_2 (BiTree T)
{
    int count=0;
    BiTree temp = T;
   while(T->lchild != NULL)
   { 
       T = T->lchild;
       count++;
   }
   while(temp->rchild !=NULL)
   { 
       count++;
     temp = temp->rchild;
   }
   return count;
}
int main(void)
{ 
    BiTree T=NULL;
//HUB##A##OQU###AN###
    printf("\n创建一棵二叉树:\n");
    CreateBiTree(&T);  /*建立一棵二叉树T*/

    printf("\n      先序遍历结果为:");
    PreOrder(T);       /*先序遍历二叉树*/

    printf("\n非递归先序遍历结果为:"); 
    NRPreOrder(T);
    printf("\n");

    printf("\n      中序遍历结果为:");
    MidOrder(T);
    printf("\n非递归中序遍历结果为:");
    NRMidOrder(T); 
    printf("\n");

    printf("\n      后序遍历结果为:");
    PostOrder(T);
    printf("\n非递归后序遍历结果为:");
    NRPostOrder(T); 
    printf("\n");

    printf("\n      层次遍历结果为:");
    LevelOrder(T);     /*层次遍历二叉树*/
    printf("\n");
    printf("\n       树的深度为:%d",depth(T));

    printf("\n 不用递归求深度为:%d",depth_2(T));

    printf("\n       节点数量为:%d\n",count);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡宝全

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值