《数据结构》实验报告五:二叉树

这篇具有很好参考价值的文章主要介绍了《数据结构》实验报告五:二叉树。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、实验目的

1、掌握二叉树的基本特性

2、掌握二叉树的先序、中序、后序递归遍历算法

3、理解二叉树的先序、中序、后序非递归遍历算法

4、通过求二叉树的深度叶子结点数层序遍历等算法,理解二叉树的基本特性

二、实验预习

说明以下概念

1、二叉树:

       二叉树是n个结点(n>=0)的有限集合。该集合或为空集(n=0);或由一个根节点两棵互不相交的、分别称为该根节点的左子树右子树的二叉树构成。(递归定义)

2、递归遍历:

       二叉树的递归遍历常见有三种:前序、中序、后序遍历。(这里的前、中、后指的是根结点的访问次序)

       前序遍历按照“根结点->左孩子->右孩子”的顺序访问结点;

       中序遍历按照“左孩子->根结点->右孩子”的顺序访问结点;

       后序遍历按照“左孩子->右孩子->根结点”的顺序访问结点。

       其中在访问左孩子和右孩子的时候依然使用对应的前序、中序或后序遍历。

3、非递归遍历:

       利用实现的非递归遍历,也分为三种:前序、中序、后序遍历。

       以中序遍历为例,按照“左孩子->根结点->右孩子”的顺序进行访问。

       从一棵二叉树的根节点开始,依次访问该根结点的左孩子、左孩子的左孩子……,并保存一路走过的根节点(依次入栈),直至左子树为空。

       左子树为空说明该左孩子遍历完成,接着根节点出栈,并访问出栈的根节点(该根节点为最后经过的根节点),然后借助出栈的根节点进入该根节点的右子树继续进行访问。利用栈后入先出的特点,实现了二叉树的非递归遍历。

4、层序遍历:

       从一棵树的根结点开始,按照从上到下从左到右的顺序依次访问树中的每一个结点。

三、实验内容和要求

1、阅读并运行下面程序,根据输入写出运行结果,并画出二叉树的形态。

#include<stdio.h>
#include<malloc.h>
#define MAX 20

typedef struct BTNode{         /*二叉树结点结构声明*/
	char data ;                /*节点数据*/
	struct BTNode *lchild;
	struct BTNode *rchild ;    /*孩子指针*/
}*BiTree;

void createBiTree(BiTree *t){  /*先序遍历创建二叉树*/
	char s;
	BiTree q;
	printf("\nplease input data:(exit for #)");
	s=getche();   //getche:输入后立即从控制台取字符,不以回车为结束(带回显)
	//输入#,说明该树为空
	if('#' == s)
    {
	    *t = NULL;
        return;
    }
    //输入非'#':为根结点分配空间
	q = (BiTree)malloc(sizeof(struct BTNode));
	/*分配失败*/
	if( !q )
    {
        printf("Memory alloc failure!");
        exit(0);
    }
    /*分配成功*/
	q->data = s;
	*t = q;
	createBiTree(&q->lchild);  /*递归建立左子树*/
	createBiTree(&q->rchild);  /*递归建立右子树*/
}

void PreOrder(BiTree p){  /*先序遍历二叉树*/
    if( p!= NULL )
    {
       	printf("%c",p->data);
       	PreOrder(p->lchild);
       	PreOrder(p->rchild);
    }
}

void InOrder(BiTree p){  /*中序遍历二叉树*/
    if( p!= NULL )
    {
 	    InOrder(p->lchild);
        printf("%c",p->data);
   	    InOrder(p->rchild);
    }
}

void PostOrder(BiTree p){  /*后序遍历二叉树*/
    if( p!= NULL )
    {
    	PostOrder(p->lchild);
       	PostOrder(p->rchild);
       	printf("%c",p->data);
    }
}

void Preorder_n(BiTree p){  /*先序遍历的非递归算法*/
    BiTree stack[MAX];  //准备一个顺序栈存储结点
    BiTree q;
    int top = 0;  //top=0:栈空
    int i;
    for(i=0;i<MAX;i++)    /*初始化栈*/
        stack[i] = NULL;
    q = p;  //设置q指向待遍历的二叉树
    while( q != NULL )
    {
        printf("%c",q->data);  //先访问根节点
        if(q->rchild != NULL)
            stack[top++] = q->rchild;

        if(q->lchild != NULL)
            q = q->lchild;
        //结点的左孩子为空,说明该结点的左子树访问结束,进入下一二叉树(出栈)
        else
        {
            if(top > 0)
               q = stack[--top];
            else
               q = NULL;
        }
    }
}

void release(BiTree t){ /*释放二叉树空间*/
  	if(t!=NULL)
    {
    	release(t->lchild);
    	release(t->rchild);
    	free(t);
  	}
}

int main(){
    BiTree t = NULL;
    createBiTree(&t);
    printf("\n\nPreOrder the tree is:");
    PreOrder(t);
    printf("\n\nInOrder the tree is:");
    InOrder(t);
    printf("\n\nPostOrder the tree is:");
    PostOrder(t);
    printf("\n\n先序遍历序列(非递归):");
    Preorder_n(t);
    release(t);
    return 0;
}
  • 运行程序:

       输入:ABC##DE#G##F###

  • 运行结果:

《数据结构》实验报告五:二叉树

  • 二叉树形态:

《数据结构》实验报告五:二叉树

2、在上题中补充求二叉树中结点总数算法(提示:可在某种遍历过程中统计遍历的结点数),并在主函数中补充相应的调用验证正确性。

算法代码(递归算法):

int Num_of_Nodes(BiTree t){  /*求二叉树t的结点总数,函数返回值即结点总数*/
    BiTree q;
    q = t;

    //二叉树为空,直接返回0
    if( !q )
        return 0;

    //二叉树非空,总结点数 = 1 + 左子树的总结点数 + 左子树的总结点数
    int num_l = Num_of_Nodes(q->lchild);
    int num_r = Num_of_Nodes(q->rchild);

    return (1 + num_l + num_r);
}

主函数补充代码:

int main(){
    BiTree t = NULL;
    createBiTree(&t);
    printf("\n\nPreOrder the tree is:");
    PreOrder(t);
    printf("\n\nInOrder the tree is:");
    InOrder(t);
    printf("\n\nPostOrder the tree is:");
    PostOrder(t);
    printf("\n\n先序遍历序列(非递归):");
    Preorder_n(t);

    //主函数添加代码
    printf("\n\n此二叉树结点总数为:%d",Num_of_Nodes(t));

    release(t);
    return 0;
}

运行结果:

《数据结构》实验报告五:二叉树

3、在上题中补充求二叉树中叶子结点总数算法(提示:可在某种遍历过程中统计遍历的叶子结点数),并在主函数中补充相应的调用验证正确性。

算法代码(递归算法):

int Num_of_LeafNodes(BiTree t){  /*求二叉树t的叶子结点总数,函数返回值即叶子结点总数*/
    BiTree q;
    q = t;

    //二叉树为空,直接返回0
    if( !q )
        return 0;
    //结点的左右子树均为空,则该结点为叶子结点
    if( !(q->lchild) && !(q->rchild) )
        return 1;

    //二叉树非空,叶子结点总数 = 左子树的叶子结点总数 + 右子树的叶子结点总数
    int num_l = Num_of_LeafNodes(q->lchild);
    int num_r = Num_of_LeafNodes(q->rchild);

    return (num_l + num_r);
}

主函数补充代码:

int main(){
    BiTree t = NULL;
    createBiTree(&t);
    printf("\n\nPreOrder the tree is:");
    PreOrder(t);
    printf("\n\nInOrder the tree is:");
    InOrder(t);
    printf("\n\nPostOrder the tree is:");
    PostOrder(t);
    printf("\n\n先序遍历序列(非递归):");
    Preorder_n(t);

    //主函数添加代码
    printf("\n\n此二叉树结点总数为:%d",Num_of_Nodes(t));
    printf("\n\n此二叉树叶子结点总数为:%d",Num_of_LeafNodes(t));

    release(t);
    return 0;
}

运行结果:

《数据结构》实验报告五:二叉树

4、在上题中补充求二叉树深度算法,并在主函数中补充相应的调用验证正确性。

算法代码(递归算法):

int Depth_of_BiTree(BiTree t){  /*求二叉树t的深度,函数返回值即二叉树深度*/
    BiTree q;
    q = t;

    //二叉树为空,直接返回0
    if( !q )
        return 0;

    //二叉树非空,深度 = 1 + Max(左子树深度,右子树深度)
    int dep_l = Depth_of_BiTree(q->lchild);
    int dep_r = Depth_of_BiTree(q->rchild);
    int dep = 1 + ( (dep_l > dep_r)?dep_l:dep_r );

    return dep;
}

主函数补充代码: 

int main(){
    BiTree t = NULL;
    createBiTree(&t);
    printf("\n\nPreOrder the tree is:");
    PreOrder(t);
    printf("\n\nInOrder the tree is:");
    InOrder(t);
    printf("\n\nPostOrder the tree is:");
    PostOrder(t);
    printf("\n\n先序遍历序列(非递归):");
    Preorder_n(t);

    //主函数添加代码
    printf("\n\n此二叉树结点总数为:%d",Num_of_Nodes(t));
    printf("\n\n此二叉树叶子结点总数为:%d",Num_of_LeafNodes(t));
    printf("\n\n此二叉树深度为:%d",Depth_of_BiTree(t));

    release(t);
    return 0;
}

运行结果:

《数据结构》实验报告五:二叉树

5、补充二叉树中序非递归遍历算法,并给出运行结果。

算法代码:

void Inorder_n(BiTree p){  /*中序遍历的非递归算法*/
    BiTree stack[MAX];     //准备一个顺序栈存储结点
    BiTree q;
    int top = 0;           //top = 0:栈空
    int i;
    for(i=0;i<MAX;i++)     /*初始化栈*/
        stack[i] = NULL;

    q = p;  //q指向遍历的二叉树
    while( q || top > 0 )
    {
        //结点非空
        if( q )
        {
            stack[top++] = q;  //根节点入栈
            q = q->lchild;     //进入左子树
        }

        //结点为空,栈非空
        else
        {
            q = stack[--top];      //根结点出栈
            printf("%c",q->data);  //访问根节点
            q = q->rchild;         //进入右子树
        }
    }
}

 主函数补充代码:

int main(){
    BiTree t = NULL;
    createBiTree(&t);
    printf("\n\nPreOrder the tree is:");
    PreOrder(t);
    printf("\n\nInOrder the tree is:");
    InOrder(t);
    printf("\n\nPostOrder the tree is:");
    PostOrder(t);
    printf("\n\n先序遍历序列(非递归):");
    Preorder_n(t);

    //主函数添加代码
    printf("\n\n此二叉树结点总数为:%d",Num_of_Nodes(t));
    printf("\n\n此二叉树叶子结点总数为:%d",Num_of_LeafNodes(t));
    printf("\n\n此二叉树深度为:%d",Depth_of_BiTree(t));
    printf("\n\n中序遍历序列(非递归):");
    Inorder_n(t);

    release(t);
    return 0;
}

运行结果:

《数据结构》实验报告五:二叉树文章来源地址https://www.toymoban.com/news/detail-448810.html

到了这里,关于《数据结构》实验报告五:二叉树的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构-二叉树】二叉树

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年02月07日
    浏览(40)
  • 数据结构:搜索二叉树 | 平衡二叉树

    博客写的代码都放在这里:gitee仓库链接 1.二叉搜索树 1.1.基本概念 二叉搜索树又称二叉排序树, 可以为空,如果不为空具有以下性质的二叉树 : 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的

    2024年01月23日
    浏览(49)
  • 【数据结构和算法】--- 二叉树(3)--二叉树链式结构的实现(1)

    在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在大家对二叉树结构掌握还不够深入,且为了方便后面的介绍,此处手动快速创建一棵简单的二叉树,快速进入二叉树操作学习,等二叉树结构了解的差不多时,我们反过头再来研

    2024年01月25日
    浏览(48)
  • 【数据结构】二叉树——链式结构

    目录  一、前置声明 二、二叉树的遍历 2.1 前序、中序以及后序遍历 2.2 层序遍历 三、节点个数以及高度 3.1 节点个数 3.2 叶子节点个数 3.3 第k层节点个数 3.4 二叉树的高度/深度 3.5 查找值为x的节点 四、二叉树的创建和销毁 4.1 构建二叉树 4.2 二叉树销毁 4.3 判断二叉树

    2024年02月16日
    浏览(35)
  • 【数据结构】二叉树——顺序结构

    由于每个节点都 只有一个父节点 ,所以我们可通过双亲来表示一棵树。具体方式通过 数组的形式 实现。 根节点的下标为0 按照层序从上到下排序 每层从左向右递增 表示形式: 二维数组 数据的列标为0 ,只需确定行标,即可锁定位置 根节点的父节点下标为 -1 列标为1存父节

    2024年02月02日
    浏览(44)
  • 数据结构-二叉树-二叉树左右孩子交换(递归)

     注:本文采用队列和递归的算法进行创建和层次遍历。同时不能采用BFS和DFS,因为需要把当前根节点的左孩、右孩勾链并输入才能递归下一个根节点; 队列用于存储此时应该递归的根节点; 格式:每一行尾不能有空格; Description 根据输入利用二叉链表创建二叉树,并将所

    2024年02月04日
    浏览(43)
  • 【数据结构】二叉树链式结构

    🚀write in front🚀 📜所属专栏:初阶数据结构 🛰️博客主页:睿睿的博客主页 🛰️代码仓库:🎉VS2022_C语言仓库 🎡您的点赞、关注、收藏、评论,是对我最大的激励和支持!!! 关注我,关注我,关注我 , 你们将会看到更多的优质内容!!   在之前的二叉树的顺序结

    2024年02月03日
    浏览(30)
  • 【数据结构】二叉树的介绍和二叉树堆

    💓作者简介: 加油,旭杏,目前大二,正在学习 C++ , 数据结构 等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏👀 🚚代码仓库:旭日东升 1👀 🌹欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖        树这一概念,在我们刚开始听说的时候会觉得

    2024年01月20日
    浏览(45)
  • 【数据结构】 二叉树理论概念!一文了解二叉树!

    🎥 屿小夏 : 个人主页 🔥个人专栏 : 数据结构解析 🌄 莫道桑榆晚,为霞尚满天! 什么是二叉树?二叉树的组成构造是什么样的?我们将由浅入深,循序渐进的方式把二叉树给搞明白,让你彻底了解二叉树! 树是一种非线性的数据结构,它是由n(n=0)个有限结点组成一

    2024年02月05日
    浏览(41)
  • 数据结构之二叉树和平衡二叉树

    1、二叉树: 2、平衡二叉树:

    2024年04月17日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包