• 二叉树遍历的递归实现详解(先序、中序、后序和层次遍历)


    由二叉树的定义可知,一棵二叉树由根结点、左子树和右子树三部分组成。因此,只要遍历了这三个部分,就可以实现遍历整个二叉树。若以D、L、R分别表示遍历根结点、左子树、右子树,则二叉树的递归遍历可以有一下四种方式:

    先序遍历(DLR)

    先序遍历的递归过程为

    (1)访问根结点
    (2)先序遍历根结点的左子树
    (3)先序遍历根结点的右子树

    举例:

    代码:

    void PreOrder(BiTree bt)
    {
        if(bt ==NULL)return;    //递归的结束条件----某结点为空时
        printf("%d",bt->data);      //这里用printf data表示访问结点的数据域
        PreOrder(bt->lchild);   //递归遍历左孩子
        PreOrder(bt->rclild);   //递归遍历右孩子
    }
    

    中序遍历(LDR

    (1)中序遍历根结点的左子树
    (2)访问根结点
    (3)中序遍历根结点的右子树

    举例:

    代码:

    void InOrder(BiTree bt)
    {
        if(bt ==NULL)return;    //递归的结束条件----某结点为空时
        InOrder(bt->lchild);   //递归遍历左孩子
        printf("%d",bt->data);      //这里用printf data表示访问结点的数据域
        InOrder(bt->rclild);   //递归遍历右孩子
    }
    

    后序遍历(LRD)

    (1)后序遍历二叉树的左子树
    (2)后序遍历二叉树的右子树
    (3)访问根结点。

    举例:

    代码:

    void PostOrder(BiTree bt)
    {
        if(bt ==NULL)return;    //递归的结束条件----某结点为空时
        PostOrder(bt->lchild);   //递归遍历左孩子
        PostOrder(bt->rclild);   //递归遍历右孩子
        printf("%d",bt->data);      //这里用printf data表示访问结点的数据域
    }     
    

    层次遍历

    (1)根结点入队列
    (2)根结点出队列,根结点的左子树、右子树相继入队列
    (3)根结点的左子树结点出队列,左子树结点的左子树、右子树相继入队列
    (4).......

    举例:

    代码:

    //层次遍历二叉树
    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 ;  //若右子树非空,则入队列 
    		} 
    	}	
    } 
    

    最终代码:

    #include<stdio.h>
    #include<stdlib.h>
    #define MAX 20
    typedef char TElemType;
    typedef int Status;
    typedef struct BiTNode
    {
    	TElemType data;   
    	struct BiTNode *lchild,*rchild;	//左右孩子的指针 
    } BiTNode,*BiTree;
    //先序创建二叉树
    void CreateBiTree(BiTree *T)
    {
    	char ch;
    	ch=getchar();
    	if(ch=='#')(*T)=NULL;   //#代表空指针
    	else
    	{
    		(*T)=(BiTree)malloc(sizeof(BiTNode));  //申请节点
    		(*T)->data=ch;	    //生成跟节点
    		CreateBiTree(&(*T)->lchild);
    		CreateBiTree(&(*T)->rchild);
    	}	
    } 
    //先序输出二叉树
    void PreOrder(BiTree T)
    {
    	if(T)
    	{
    		printf("%2c",T->data);   //访问根节点,此处为输出根节点的数据值	
    		PreOrder(T->lchild);     //先序遍历左子树
    		PreOrder(T->rchild);     //先序遍历右子树
    	} 
    } 
    //中序输出二叉树
    void InOrder(BiTree T)
    {
    if(T)
    	{
    		InOrder(T->lchild);
    		printf("%2c",T->data);
    		InOrder(T->rchild);
    	}	
    } 
    //后序输出二叉树
    void PostOrder(BiTree T)
    {
    if(T)
    	{
    		PostOrder(T->lchild);
    		PostOrder(T->rchild);
    		printf("%2c",T->data);
    	}	
    } 
    //层次遍历二叉树
    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 main()
    {
    	BiTree T=NULL;
    	printf("
     创建一棵二叉树: 
    ");
    	CreateBiTree(&T);  //创建二叉树
    	printf("
    先序遍历的结果为:
    ");
    	PreOrder(T);  //先序遍历
    	printf("
    中序遍历的结果为:
    ");
    	InOrder(T);  //中序遍历 
    	printf("
     后序遍历的结果为: 
    ");
    	PostOrder(T); 
    	printf("
     层次遍历的结果为: 
    ");
    	LevelOrder(T); //层次遍历
    	printf("
     树的深度为:%d
    ",depth(T)); 
    }
    
    

    结果示例:

    大家喜欢的话可以点个赞,有错误的地方请务必在评论区指出哟

  • 相关阅读:
    用例图解析
    A B C D类网络地址
    B-树特征
    常用的中间代码
    UML图
    关于文件索引的一道习题
    数据流图的一些原则
    系统总线
    各种排序方法的时间复杂度、空间复杂度和稳定性统计表
    模拟银行自助终端系统
  • 原文地址:https://www.cnblogs.com/kangna/p/11846154.html
Copyright © 2020-2023  润新知