二叉树1:二叉树的基本运算

1. (简答题)

       编写一个程序,实现二叉树的基本运算,具体要求如下:(指定示范实例1:P243图7.34。指定示范实例2:P201图7.13 )

1,括号表示法输出该树。

2,输入一个结点的值,输出该结点的左,右孩子的值。(要能测试错误数据)

3,输出该二叉树的高度。

4,输出该二叉树结点的个数。

5,输出该二叉树双分支结点的个数。

6,输出该二叉树单分支结点的个数。

7,输出该二叉树叶子结点的个数。

8,输出该二叉树的宽度。(宽度为每层结点数的最大值)

9,(选做题)任意给定该二叉树的两个结点,输出它们的最近的公共祖先。(例:对P243图7.34,输入J, N,它们的祖先是H,E,B,A,最近的祖先是H。  另外一组测试数据为:L,E的公共祖先是:E。 )

10,销毁该二叉树。

//二叉树
#include<bits/stdc++.h>
using namespace std;
#define MAX 10000
#define MIN -1
typedef char ch;
int ans=MIN,w[100]={0};//假设这课树的高度不超100
//首先每个节点的属性如下有数据域,左右孩子
typedef struct BTnode
{ch data;struct BTnode *lchild;struct BTnode *rchild;
}BT;//注意这个是节点的定义
//解读树,用二叉链的形式
void CreatBtree(BT *&B1,ch *str)//输入我们创建的树和树的括号表示法
{//B1是我们的树,str是括号表示法的那串字符BT *st[MAX],*p;//B作为一个顺序栈。p就是我们扫描的元素int top=-1,k,j=0;ch l;//top是表示栈顶,k表示左右孩子,j是遍历a用的B1=NULL;l=str[j];while(l!='\0'){//总结一下:(入栈(表示这条分支的开始),)退栈(因为结束了),遇到元素就创建节点,//遇到逗号改k(左右孩子),见下面的注释一switch (l) {case '(':top++;st[top]=p;k=1;break;case ')':top--;break;case ',':k=2;break;default:p=new BT;p->data=l;p->lchild=p->rchild=NULL;if(B1==NULL)//头结点B1=p;else{switch (k) {case 1:st[top]->lchild=p;break;case 2:st[top]->rchild=p;break;}}}j++;l=str[j];}
}
//以值找p
BT *Findmyposition(BT *B1,ch str)
{BT *p;if(B1==NULL)//空树找不到return NULL;else if(B1->data==str)//根是的话就返回根return B1;else{//否则开始递归找(先搜索左)p=Findmyposition(B1->lchild,str);//p如果最后为空,说明没找到 ,那就找右节点//如果找到就不找了if(p!=NULL)return p;elsereturn Findmyposition(B1->rchild,str);}}
//寻找左右孩子
BT *Lchildnode(BT *p)//返回一个地址
{return p->lchild;//理解上面创建的过程就可以理解这个
}
BT *Rchildnode(BT *p)
{return p->rchild;
}
//高度
int BTheight(BT *B1)
{int l,r;if(B1==NULL)return 0;else{l=BTheight(B1->lchild);r=BTheight(B1->rchild);return ((l>r)?l+1:r+1);	}
}
//节点数
int BTcount(BT *B1)
{if(B1==NULL)return 0;elsereturn BTcount(B1->lchild)+BTcount(B1->rchild)+1;
}
int BTdoublecount(BT *B1)
{if(B1==NULL)return 0;else if(B1->lchild!=NULL&&B1->rchild!=NULL)return BTdoublecount(B1->lchild)+BTdoublecount(B1->rchild)+1;elsereturn BTdoublecount(B1->lchild)+BTdoublecount(B1->rchild);
}
int BTsinglecount(BT *B1)
{if(B1==NULL)return 0;else if((B1->lchild!=NULL&&B1->rchild!=NULL)||(B1->lchild==NULL&&B1->rchild==NULL))return BTsinglecount(B1->lchild)+BTsinglecount(B1->rchild);elsereturn BTsinglecount(B1->lchild)+BTsinglecount(B1->rchild)+1;
}
int BTleavescount(BT *B1)
{if(B1==NULL)return 0;else if(B1->lchild==NULL&&B1->rchild==NULL)return BTleavescount(B1->lchild)+BTleavescount(B1->rchild)+1;elsereturn BTleavescount(B1->lchild)+BTleavescount(B1->rchild);
}
//宽度计算
int BTwcount(BT *B1,int h)
{if(B1==NULL)return 0;w[h]++;ans=((w[h]>ans)?w[h]:ans);BTwcount(B1->lchild,h+1);BTwcount(B1->rchild,h+1);return ans;
}
bool Findallparent(BT *B1,ch str,stack<ch>&s1)
{if(B1==NULL)return false;s1.push(B1->data);if(B1->data==str)//为什么这样子,根据题目提示,本身也可以是祖先,所以我们把本身也压入.return true;//找到了就结束bool flag=Findallparent(B1->lchild,str,s1);//没搜索到本点就继续if(flag)return true;//如果在左支找到了,退出flag=Findallparent(B1->rchild,str,s1);//否则右支if(flag)return true;s1.pop();//没找到就回溯return false;
}
//寻找最近共同祖先
ch Findsameparent(BT *B1,ch str1,ch str2)
{stack<ch> s1,s2;Findallparent(B1,str1,s1);Findallparent(B1,str2,s2);int p1=s1.size(),p2=s2.size();if(p1>p2)//令两栈位于同一层{int n=p1-p2;while(n){s1.pop();n--;}}else{int n=p2-p1;while(n){s2.pop();n--;}}while(s1.top()!=s2.top()){s1.pop();s2.pop();if(s1.top()==s2.top())return s1.top();}if(s1.top()==s2.top())return s1.top();return 0;
}
//销毁
void DestroyBTree(BT *&B1)
{if(B1!=NULL){//从根出发开始删除DestroyBTree(B1->lchild);DestroyBTree(B1->rchild);delete B1;}
}
int main()
{int n;BT *B1;B1=new BT;ch a[MAX];cout<<"请选择您要测试的样例(输入1或2)";cin>>n;cout<<endl;if(n==1){cout<<"1.括号表示法表示这个树(样例一):A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I))"<<endl<<endl;strcpy(a, "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I))");}else if(n==2){cout<<"1.括号表示法表示这个树(样例二):A(B(D(,G),),C(E,F))"<<endl<<endl;strcpy(a, "A(B(D(,G),),C(E,F))");}else{cout<<"WARNING:what are you doing?"<<endl<<endl<<"输入1或2,ok?"<<endl<<endl;//防伪标识return 1;}CreatBtree(B1,a);//输入一个节点值,输出左右孩子cout<<"2.请您输入您要查询的节点的值:";ch o;cin>>o;cout<<endl;BT *p=Findmyposition(B1,o);if(p==NULL)cout<<"您的输入错误,该树无此结点!"<<endl<<endl;else{ BT *k=Lchildnode(p);if(!k)cout<<o<<"无左孩子!"<<endl<<endl;elsecout<<o<<"的左孩子是:"<<k->data<<endl<<endl;k=Rchildnode(p);if(!k)cout<<o<<"无右孩子!"<<endl<<endl;elsecout<<o<<"的右孩子是:"<<k->data<<endl<<endl;}//输出高度cout<<"3.该二叉树的高度为:"<<BTheight(B1)<<endl<<endl;cout<<"4.该二叉树的节点个数为:"<<BTcount(B1)<<endl<<endl;cout<<"5.该二叉树双分支结点的个数:"<<BTdoublecount(B1)<<endl<<endl;cout<<"6.该二叉树单分支结点的个数:"<<BTsinglecount(B1)<<endl<<endl;cout<<"7.该二叉树叶子结点的个数:"<<BTleavescount(B1)<<endl<<endl;cout<<"8.该二叉树的宽度:"<<BTwcount(B1,0)<<endl<<endl;cout<<"9.请输入二叉树的两个结点:";ch h,x;cin>>h>>x;cout<<endl;cout<<"它们的最近的公共祖先是:"<<Findsameparent(B1,h,x)<<endl<<endl;cout<<"是否继续?(0退出,1继续)";int y;cin>>y;cout<<endl;while(y){cout<<"9.请输入二叉树的两个结点:";cin>>h>>x;cout<<endl;cout<<"它们的最近的公共祖先是:"<<Findsameparent(B1,h,x)<<endl<<endl;cout<<"是否继续?(0退出,1继续)";cin>>y;cout<<endl;}//销毁二叉树DestroyBTree(B1);cout<<"10.销毁二叉树成功!!!"<<endl<<endl;return 0;
} //我的蒟蒻见解
//注释一:我对(的理解是递归中根的确立,先放到栈顶,在未遇到)之前他的左孩子就接到栈顶的
//左指针域,右孩子接到右指针域,如果是左孩子遇到了(那就左孩子入栈,继续这样子的步骤,直到遇到
//)表示结束最近的那个根的左右寻找,然后一步一步回去,类似dfs不完全像,我做了个图,可以参考一下!
//发现了一个技巧,字母后面的(直接看出这个字母进栈的标志)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/7337.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

04.1.添加多个监控同步其他主机

添加多个监控&同步其他主机 1.首先在agent配置文件中存在Include的&#xff0c;也就是说明&#xff0c;可以配置多个监控项并且同步到其他主机上的进行使用&#xff1b; 2.主机之间互相推送配置文件即可&#xff1b; 开始测试 我这里实在agent节点上直接在路径/etc/zabbi…

Go实现树莓派控制舵机

公式说明 毫秒&#xff08;ms&#xff09;是时间的单位&#xff0c;赫兹&#xff08;Hz&#xff09;是频率的单位&#xff0c;而DutyMax通常是一个PWM&#xff08;脉冲宽度调制&#xff09;信号中表示最大占空比的值。以下是它们之间的关系和一些相关公式&#xff1a; 频率&…

Python内置函数min()详解

Python中的min()函数是一个内置函数&#xff0c;用于找出给定参数或可迭代对象中的最小值。 函数定义 min()函数可以有两种不同的使用方式&#xff1a; min(iterable, *[, defaultobj, keyfunc]) min(arg1, arg2, *args[, keyfunc])iterable&#xff1a;一个可迭代对象。def…

设计模式之建造者模式BuilderPattern(七)

一、建造者模式 建造者模式&#xff08;Builder Pattern&#xff09;使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 二、代码实例 1、OrderItem类 Data&#xff1a;这是Lombok中提供的Ge…

【linux软件基础知识】-cdev_alloc

struct cdev *cdev_alloc(void) {struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);if <

并发编程陷阱:32位CPU下long写操作的线程安全漏洞

1. 现象描述 1.1 Bug问题简述 在多线程环境下操作共享数据时&#xff0c;往往面临各种并发问题。其中&#xff0c;一种常见的情况是&#xff0c;即使一段代码在单线程下执行没有问题&#xff0c;当它在多线程环境下执行时&#xff0c;却可能由于线程安全问题导致意想不到的Bu…

ADS过孔---过孔建模自动化

当前快速建模的方法有两类&#xff1a;一是脚本自动化&#xff0c;也就是今天要分享的方法&#xff0c;但该方法需要工程师有基本的脚本编辑能力&#xff0c;然后根据自己的需要去修改&#xff0c;难度较大一点点&#xff1b;二是参数化建模&#xff0c;也就是在GUI界面输入相应…

百度语音识别开发笔记

目录 简述 开发环境 1、按照官方文档步骤开通短语音识别-普通话 2、创建应用 3、下载SDK 4、SDK集成 5、相关接口简单说明 5.1权限和key 5.2初始化 5.3注册回调消息 5.4开始转换 5.5停止转换 6、问题 简述 最近想做一些语音识别的应用&#xff0c;对比了几个大厂…

华为手机连接电脑后电脑无反应、检测不到设备的解决方法

本文介绍华为手机与任意品牌电脑连接时&#xff0c;出现连接后电脑无反应、检测不到手机连接情况的解决方法。 最近&#xff0c;因为手机的存储空间愈发紧缺&#xff0c;所以希望在非华为电脑中&#xff0c;将华为手机内的照片、视频等大文件备份、整理一下。因此&#xff0c;需…

aardio爬虫) 实战篇:逆向有道翻译web接口

前言 之前的文章把js引擎(aardio封装库) 微软开源的js引擎(ChakraCore))写好了&#xff0c;这篇文章整点js代码来测一下bug。测试网站&#xff1a;https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻译js逆向&#xff08;MD5加密&#xff0c;AES加密&…

cmake进阶:定义函数的内部变量

一. 简介 前一篇文章学习 cmake中的定义函数基本用法。文章如下&#xff1a; cmake进阶&#xff1a;定义函数的使用方法-CSDN博客 本文继续学习 cmake中的定义函数&#xff0c;主要学习函数的内部变量。 二. cmake进阶&#xff1a;定义函数的内部变量 上一篇文章说过&…

Elasticsearch:理解人工智能相似性搜索

理解相似性搜索&#xff08;也称为语义搜索&#xff09;的指南&#xff0c;这是人工智能最新阶段的关键发现之一。 最新阶段人工智能的关键发现之一是根据相似性搜索和查找文档的能力。相似性搜索是一种比较信息的方法&#xff0c;其基于含义而非关键字。 相似性搜索也被称为语…

Stable Diffusion学习记录

文章目录 前言电脑配置推荐环境搭建下载地址安装步骤步骤一&#xff0c;打开下载的秋叶整合包&#xff0c;路径秋叶整合包/sd-wenui-aki步骤二&#xff0c;打开下载好的sd-webui-aki-v4.8.7解压包 Stable Diffusion软件配置&#xff0c;插件安装&#xff0c;模型下载Stable Dif…

从ETL与ELT谈起,理解数仓的任务

最近有个朋友&#xff0c;有几十 PB 的异构数据&#xff0c;数据源包括 MySQL、DB2、Oracle、CSV、磁带机&#xff0c;等等&#xff0c;然后他需要把这些数据中的一些信息做关联整合&#xff0c;从这几十 PB 的数据中提取出若干业务字段到数据仓库&#xff0c;做统一分析。 数…

Codeforces Round 943 (Div. 3) C-G

C. Assembly via Remainders 思路&#xff1a; 我们可以注意到&#xff0c;数组的长度只有 500 500 500 &#xff0c;并且每个数的大小都在 500 500 500 以内&#xff0c;再看向这题&#xff0c;容易知道&#xff0c;当第一个数确定之后&#xff0c;之后所有的数字都会确定下…

uniapp自定义websocket类实现socket通信、心跳检测、连接检测、重连机制

uniapp自定义websocket类实现socket通信、心跳检测、检测连接、重连机制&#xff0c;仿vue-socket插件功能实现发送序列号进行连接检测&#xff0c;发送消息时42【key,value】格式&#xff0c;根据后端返回数据和需要接收到的数据做nsend与onSocketMessage的修改 import {publ…

leetcode-没有重复项的全排列-97

题目要求 思路 1.递归&#xff0c;如果num和n的元素个数一样就可以插入res中了&#xff0c;这个作为递归的结束条件 2.因为这个题是属于排列&#xff0c;并非组合&#xff0c;两者的区别是排列需要把之前插入的元素在回退会去&#xff0c;而组合不需要&#xff0c;因此会存在一…

14【PS作图】像素画尺寸大小

【背景介绍】本节介绍像素图多大合适 下图是160*144像素大小,有一个显示文本的显示器,还有一个有十几个键的键盘 像素画布尺寸 电脑16像素,但还有一个显示屏 下图为240*160 在场景素材,和对话素材中,用的是不同尺寸的头像,对话素材中的头像会更清楚,尺寸会更大 远处…

【软考高项】三十三、质量管理

一、管理基础 质量定义 国际标准&#xff1a;反映实体满足主体明确和隐含需求的能力的特性总和。 国家标准&#xff1a;一组固有特性满足要求的程度。固有特性是指在某事或某物中本来就有的&#xff0c;尤其是那种永久的可区分的特征。 ➢ 对产品来说&#xff0c;例如…

Flask 路由基础和封装

Flask 路由 Flask中的路由是用来定义应用程序中的 URL 和处理函数之间的映射关系的&#xff0c;而URL则是用户访问应用程序的入口点。通过路由,我们可以将用户访问的 URL 映射到对应的视图函数上,从而实现不同的功能。 一、路由基础 1.定义路由: 我们可以使用 app.route() …