二叉树的基本操作_以二叉链表表示二叉树,建立一棵二叉树(算法5.3);-程序员宅基地

技术标签: C/C++  二叉树  二叉树基本操作  数据结构  

注:实验用书为 数据结构 C语言版 第2版,人民邮电出版社出版。
实验题目:学生管理系统的设计与实现
实验环境:Visual C++ 6.0或其他C++环境
一、实验目的
1、掌握二叉树的定义;
2、掌握二叉树的基本操作,如二叉树的建立、遍历、结点个数统计、树的深度计算等。
二、实验内容
(一)用递归的方法实现以下算法:
1、以二叉链表表示二叉树,建立一棵二叉树(算法5.3);
2、输出二叉树的中序遍历结果(算法5.1);
3、输出二叉树的前序遍历结果(见样例);
4、输出二叉树的后序遍历结果(见样例);
5、计算二叉树的深度(算法5.5);
6、统计二叉树的结点个数(算法5.6);
7、统计二叉树的叶结点个数;
8、统计二叉树的度为1的结点个数;
9、输出二叉树中从每个叶子结点到根结点的路径。
10、交换二叉树每个结点的左孩子和右孩子;
11、设计二叉树的双序遍历(DblOrderTraverse)算法(双序遍历是指对于二叉树的每一个结点来说,先访问这个结点,再按双序遍历它的左子树,然后再一次访问这个结点,接下来按双序遍历它的右子树)。
三、测试效果如图:
这里写图片描述
这里写图片描述

四、代码如下:

#include <iostream>
using namespace std;

typedef struct Node
{//定义二叉树结构
    char data;
    struct Node *lchild,*rchild;
}*BiTree,BiTNode;

void CreateBiTree(BiTree &T)
{//先序创建二叉树
    char ch;
    cin>>ch;
    if(ch=='#') T=NULL;
    else{
        T=new BiTNode;
        T->data=ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}
void InOrderTraverse(BiTree T)
{//中序遍历
    if(T)
    {
        InOrderTraverse(T->lchild);
        cout<<T->data;
        InOrderTraverse(T->rchild);
    }
}
void PreOrderTraverse(BiTree T)
{//先序遍历
    if(T)
    {
        cout<<T->data;
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
}
void PostOrderTraverse(BiTree T)
{//后序遍历
    if(T)
    {
        PostOrderTraverse(T->lchild);
        PostOrderTraverse(T->rchild);
        cout<<T->data;
    }
}
void Copy(BiTree T,BiTree &NewT)
{//二叉树的复制
    if(T==NULL){
        NewT=NULL;
        return;
    }else
    {
        NewT=new BiTNode;
        NewT->data=T->data;
        Copy(T->lchild,NewT->lchild);
        Copy(T->rchild,NewT->rchild);
    }
}
int Depth(BiTree T)
{//树的深度
    if(T==NULL)
        return 0;
    else
    {
        int m=Depth(T->lchild);
        int n=Depth(T->rchild);
        if(m>n) return (m+1);
        else return (n+1);
    }
}
int NodeCount(BiTree T)
{//统计二叉树中结点的个数
    if(T==NULL) return 0;
    else return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
int LeafCount(BiTree T)
{//统计二叉树中叶子结点的个数
    if(!T) return 0;
    if(!T->lchild &&!T->rchild){//如果二叉树左子树和右子树皆为空,说明该二叉树根节点为叶子节点,加1.
        return 1;
    }else{
        return LeafCount(T->lchild)+LeafCount(T->rchild);
    }
}
int Node_1_Count(BiTree T)
{//统计二叉树的度为1的结点个数
    if(!T) return 0;
    if((!T->lchild)&&(T->rchild)||(T->lchild)&&(!T->rchild))
        return 1 + Node_1_Count(T->lchild) + Node_1_Count(T->rchild);
    else
        return Node_1_Count(T->lchild) + Node_1_Count(T->rchild);
}
void PrintAllPath(BiTree T, char path[], int pathlen)
{//二叉树中从每个叶子结点到根结点的路径
  int i;
  if(T != NULL) {
    path[pathlen] = T->data; //将当前结点放入路径中
    if(T->lchild == NULL && T->rchild == NULL) {//叶子结点
        for(i = pathlen; i >= 0; i--)
            cout << path[i] << " " ;
      cout << endl;
    }else{
      PrintAllPath(T->lchild, path, pathlen + 1);
      PrintAllPath(T->rchild, path, pathlen + 1);
    }
  }
}
void ExChangeTree(BiTree &T)
{//构造函数,使用递归算法进行左右结点转换
    BiTree temp;
    if(T!=NULL){//判断T是否为空,非空进行转换,否则不转换
        temp=T->lchild;
        T->lchild=T->rchild;//直接交换节点地址
        T->rchild=temp;
        ExChangeTree(T->lchild);
        ExChangeTree(T->rchild);
    }
}
void DblOrderTraverse(BiTree T)
{//二叉树的双序遍历
    if(T)
    {
        cout<<T->data;
        DblOrderTraverse(T->lchild);
        cout<<T->data;//访问两遍
        DblOrderTraverse(T->rchild);
    }
}
int main()
{
    BiTree T;
    //测试例子AB#CD##E##F#GH###
    cout<<"先序遍历输入(以#结束):";
    CreateBiTree(T);
    cout<<"中序遍历输出:";
    InOrderTraverse(T);
    cout<<endl<<"先序遍历输出:";
    PreOrderTraverse(T);
    cout<<endl<<"后序遍历输出:";
    PostOrderTraverse(T);
    cout<<endl<<"树的深度:"<<Depth(T);
    cout<<endl<<"结点的个数:"<<NodeCount(T);
    cout<<endl<<"叶结点的个数:"<<LeafCount(T);
    cout<<endl<<"度为1的结点个数:"<<Node_1_Count(T);
    cout<<endl<<"二叉树中从每个叶子结点到根结点的所有路径:"<<endl;
    char path[256];
    int pathlen=0;
    PrintAllPath(T,path,pathlen);//
    //交换二叉树每个结点的左孩子和右孩子
    BiTree tem=T;//直接复制一颗树,在不改变原树的前提下,对临时树进行交换。
    ExChangeTree(tem);
    cout<<"先序遍历输出交换后的结果:";
    PreOrderTraverse(tem);
    cout<<endl<<"双序遍历输出:";
    DblOrderTraverse(T);
    return 0;
}

五、流程图:
这里写图片描述
这里写图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/deaidai/article/details/71834241

智能推荐

Hadoop集群如何启动_hadoop集群启动命令-程序员宅基地

文章浏览阅读3.4k次。辅助namenode上的resourcemanager通过start-all.sh可能启动不了,需要进入辅namenode上手动启动(/opt/app/hadoop/sbin/hadoop-daemon.sh startresourcemanager)/opt/app/zookeeper-3.4.6/bin/zkServer.sh start(启动)/opt/app/hadoop/sbin/start-all.sh(启动)/opt/app/hadoop/sbin/start-all.sh(停止)_hadoop集群启动命令

打开别人的工程提示IAR版本不兼容问题_win7 iar 8.4无法加载工程-程序员宅基地

文章浏览阅读718次。打开别人的工程提示IAR版本不兼容问题IAR 版本不兼容问题IAR 版本不兼容问题我使用的是 STM32CUBEMX 生成的IAR工程,我自己的是 IAR 版本 8.4,打开别人的工程 8.3版本,但是提示我打开的工程版本更高,可能是IAR的一个bug吧,把cube 生成的 IAR 工程删除 然后再重新生成一个工程就好了。..._win7 iar 8.4无法加载工程

使用VMware安装Ubuntu虚拟机 - 完整教程-程序员宅基地

文章浏览阅读4.8w次,点赞89次,收藏590次。使用 VMware Workstation 16 Pro 安装 Ubuntu 虚拟机 - 完整教程_vmware安装ubuntu

商业WIFI,移动互联网的一大超级入口-程序员宅基地

文章浏览阅读116次。在2016中国互联网大会之中国WiFi应用创新大会上,中国互联网协会开发者核心价值小组秘书长于立娟发表了精彩的开幕致辞,她指出随着移动上网终端的多元化,WiFi应用已经成为移动互联网时代继浏览器、超级APP之后的又一大超级入口。 于立娟表示,“WiFi如果仅仅停留在底层入口,就会像3G...

前端常用网站-程序员宅基地

文章浏览阅读756次。MDNhttps://developer.mozilla.org/zh-CN/vue3https://v3.cn.vuejs.org/api/tshttps://www.typescriptlang.org/docs/handbook/2/keyof-types.htmlvitehttps://staging-cn.vitejs.dev/微信小程序开发文档https://developers.weixin.qq.com/miniprogram/dev/framework/微信公众平台h

php中比rbac更好的权限认证的方式auth认证类_php 节点认证-程序员宅基地

文章浏览阅读295次。RBAC是按节点进行认证的,如果要控制比节点更细的权限就有点困难了,比如页面上面的操作按钮, 我想判断用户权限来显示这个按钮, 如果没有权限就不会显示这个按钮; 再比如我想按积分进行权限认证, 积分在0-100时能干什么, 在101-200时能干什么。 这些权限认证用RABC都很困难。 下面介绍 Auth权限认证, 它几乎是全能的, 除了能进行节点认证, 上面说的RABC很难认证的两种情况,它都能_php 节点认证

随便推点

深入理解Java中的HashMap:工作原理、实现方式与使用案例分析_java中hashmap-程序员宅基地

文章浏览阅读1.6k次,点赞3次,收藏9次。HashMap是一种非常常见和实用的数据结构,它被广泛应用于Java编程中。在本文中,我们将深入探讨HashMap的工作原理、实现方式和使用案例,以帮助读者更好地理解和应用这一数据结构。_java中hashmap

HotSpot 垃圾回收-程序员宅基地

文章浏览阅读591次,点赞26次,收藏8次。主要概括了hotspot的gc机制

病毒分析之撒旦(Satan)勒索病毒分析解密(AES256 ECB算法)_撒旦查询恶意-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。病毒分析之撒旦(Satan)勒索病毒分析解密(AES256 ECB算法)0x0病毒概况撒旦勒索病毒主要是针对企业服务器用户进行感染加密其服务器上的文件并勒索用户的一种病毒。撒旦病毒通过大量漏洞利用工具,扫描入侵主机。成功入侵后加密重要文件。并生成文件用中英韩三种语言提示索要比特币赎金解密文件。0x1恶意行为1.主模块会释放大量攻击模块并执行,也会连接恶意IP下载病毒文件..._撒旦查询恶意

在Ubuntu20.04配置PX4环境_ubuntu 24.04 ppeizhi-程序员宅基地

文章浏览阅读932次,点赞7次,收藏8次。pwd=5npl 提取码:5npl。找到“软件和更新”,选择aliyun服务器,——>【关闭】——>【重新载入】,等待进度条完毕就更管成功。出现“Configuring incomplete, errors occurred!",这是由于没有将软件源改为国内软件源,如果意外退出下载,第二次进入下载的时候缓存会被锁住。在主目录下打开终端,运行以下命令,_ubuntu 24.04 ppeizhi

关于报错“! [rejected]master -> master (non-fast-forward)”的解决方法_efs/heads/master:refs/heads/master[rejected] (non--程序员宅基地

文章浏览阅读3.2w次,点赞18次,收藏58次。在遇到上述错误自己无解决时,于是开始了网上大搜索:git push -u origin master 上面命令将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了首先尝试了 命令git push -u origin master -f,然后惊喜地出现了下面错误,不能强制推送到受保护的分支随后就又找到了一个方法:先使用..._efs/heads/master:refs/heads/master[rejected] (non-fast-forward)

C# 多线程详细讲解-程序员宅基地

文章浏览阅读2.4w次,点赞68次,收藏446次。C#多线程一、基本概念1、进程首先打开任务管理器,查看当前运行的进程:从任务管理器里面可以看到当前所有正在运行的进程。那么究竟什么是进程呢?进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运_c# 多线程

推荐文章

热门文章

相关标签