树和二叉树:二叉树的基本运算算法的实现

一.前言

当前版本仅供笔者复盘

二.二叉树

2.1题目

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

1,先序遍历输出该树(带“^"标志)。

2,中序遍历输出该树(带“^"标志)。

3,后序遍历输出该树(带“^"标志)。

4,层次遍历输出该树(带“^"标志)。

5,输出该树的先序凹入表表示法(参考附件)。

6,输出该树的中序凹入表表示法。

7,输出该树的后序凹入表表示法。

8,设计一个算法把二叉树b所有的左、右子树进行交换,并用括号表示法输出该树。(要求不破坏原二叉树)

9,(选做题)输出该树相隔最远的一对结点。(例:对图1,N与I相隔最远。提示:相隔最远不一定分别在左右两棵子树上,相隔最远是两个叶子,还有一种就是叶子与根。)

图一
图二

2.2知识点总结

2.2.1排序

我的总结是

#include<bits/stdc++.h>
using namespace std;
#define MAX 10000
typedef char ch;
//首先每个节点的属性如下有数据域,左右孩子
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];}
}
//先序遍历输出该树(带“^"标志)。
void Predisplay(BT *B1)
{if(B1!=NULL){cout<<B1->data;Predisplay(B1->lchild);Predisplay(B1->rchild);}elsecout<<"^";
}
void Indisplay(BT *B1)
{if(B1!=NULL){Indisplay(B1->lchild);cout<<B1->data;Indisplay(B1->rchild);}elsecout<<"^";
}
void Postdisplay(BT *B1)
{if(B1!=NULL){Postdisplay(B1->lchild);Postdisplay(B1->rchild);cout<<B1->data;}else cout<<"^";
}
void Picdisplay(BT *B1)
{BT *p;queue<BT*>q;q.push(B1);while(!q.empty()){if(q.front()!=NULL){p=q.front();q.pop();cout<<p->data;}else{cout<<'^';q.pop();continue;}q.push(p->lchild);q.push(p->rchild);}}
//凹凸其本质就是打印的方式变了
//顺序代码还是一样的
void Pre(BT *B1,int h,int k){   //h为高度,k为左右               if(B1==NULL)    //常规判断                                return;for(int i=0;i<h*3;i++)   //越深空格越多,每次规定三个空格                cout<<" ";cout<<B1->data;for(int j=0;j<(30-3*h);j++)   //以30*30的正方形为空间,剩余填充为=         cout<<"=";if(!h)           //打印最后的字母                               cout<<"B";                               else{if(k)                                        cout<<"L";elsecout<<"R"; }cout<<endl;Pre(B1->lchild,h+1,1);Pre(B1->rchild,h+1,0);
} 
void In(BT *B1, int h, int k){if(B1==NULL)return;In(B1->lchild,h+1,1);for(int i=0; i<h*3;i++)cout<<" ";cout<<B1->data;for(int j=0; j<(30-3*h);j++)cout<<"=";if(!h)cout<<"B";else{if(k)cout<<"L";elsecout<<"R"; }cout<<endl;In(B1->rchild,h+1,0);
} 
void Post(BT *B1, int h, int k){//h为高度,k为左右if(B1==NULL)return;Post(B1->lchild,h+1,1);Post(B1->rchild,h+1,0);for(int i=0; i<h*3;i++)//越深空格越多,每次规定三个空格cout<<" ";cout<<B1->data;for(int j=0;j<(30-3*h);j++)//以30*30的正方形为空间,剩余填充为=cout<<"=";if(!h)//打印最后的字母cout<<"B";else{if(k)cout<<"L";elsecout<<"R"; }cout<<endl;
} 
//8.设计一个算法把二叉树b所有的左、右子树进行交换,并用括号表示法输出该树。(要求不破坏原二叉树)
void Exchange(BT *B1)
{BT *t;///tempif(B1==NULL)return;else if(B1->lchild!=NULL||B1->rchild!=NULL){t=B1->lchild;B1->lchild=B1->rchild;B1->rchild=t;}Exchange(B1->lchild);Exchange(B1->rchild);	
}
void Displaybtree(BT *B1){if(B1!=NULL){cout<<B1->data;if(B1->lchild!=NULL||B1->rchild!=NULL){cout<<"(";Displaybtree(B1->lchild);if(B1->rchild!=NULL)cout<<",";Displaybtree(B1->rchild);cout<<")";}}
}
//我的理解
//有两种,叶子和叶子(根的左右最深的相加不就是了吗?)
//叶子和根(这个很简单,就是深度最深的那个叶子))//但其实是错的,因为左树可以很长,所以我们的算法是寻找 共同祖先,然后相减
//不过实现起来比较棘手,就会错很多,后面请教大佬才发现(/*我蒟蒻的*/)
//这个第一步是先找叶子节点
void Findleaves(BT *B1,char a[],int &i)//a用来存节点,为了找到叶子结点
{if(!B1)//为了高级return;else {if(!B1->lchild&&!B1->rchild)a[++i]=B1->data;	Findleaves(B1->lchild,a,i);Findleaves(B1->rchild,a,i);}
}
//第二部
//上一题的寻找共同祖先
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;
}
map<char,int>trees;//储存每个结点的深度
void treedeep(BT* B1,int deep){if(B1){trees[B1->data]= deep;//求出每个结点的深dutreedeep(B1->lchild,deep+1);treedeep(B1->rchild,deep+1);}
}
void Displaynode(BT *B1)
{ch str1,str2;//存储最终答案char a[MAX];int num=0;Findleaves(B1,a,num);//把所有叶子记录在a中treedeep(B1,1);//计算所有节点的深度a[++num]=B1->data;//加上根节点int max=0;for(int i=1;i<=num;i++)//遍历{for(int j=1;j<=num;j++){if(i==j)//不和自己比continue;char lcp=Findsameparent(B1,a[i],a[j]);//两个叶子的共同祖先int len=trees[a[i]]+trees[a[j]]-2*trees[lcp];//计算路径长度if(len>max){max=len;str1=a[i];str2=a[j];}}}cout<<str1<<" "<<str2<<endl;
}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<<"1:先序遍历输出该树(带\"^\"标志):";Predisplay(B1);cout<<endl<<endl;cout<<"2:中序遍历输出该树(带\"^\"标志):";Indisplay(B1);cout<<endl<<endl;cout<<"3:后序遍历输出该树(带\"^\"标志):";Postdisplay(B1);cout<<endl<<endl;cout<<"4:层次遍历输出该树(带\"^\"标志):";Picdisplay(B1);cout<<endl<<endl;cout<<"5:该树的先序凹入表表示法:"<<endl;Pre(B1,0,1);cout<<endl<<endl;cout<<"6:该树的中序凹入表表示法:"<<endl;In(B1,0,1);cout<<endl<<endl;cout<<"7:该树的后序凹入表表示法:"<<endl;Post(B1,0,1);cout<<endl<<endl;cout<<"8:现在交换二叉树所有的左、右子树,输出为括号表示法:  ";Exchange(B1);Displaybtree(B1);cout<<endl<<endl;cout<<"9:该树相隔最远的一对结点: ";Displaynode(B1);return 0;
}

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

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

相关文章

Qt QInputDialog详解

1.简介 QInputDialog是一个对话框类&#xff0c;用于从用户那里获取一个单一的值。这个值可以是字符串、数字、或者一个列表中的选项。QInputDialog提供了一个方便的方式来快速创建一个输入对话框&#xff0c;无需自己从头开始构建。 QInputDialog支持多种输入类型&#xff1…

【CTF Web】XCTF GFSJ0475 get_post Writeup(HTTP协议+GET请求+POST请求)

get_post X老师告诉小宁同学HTTP通常使用两种请求方法&#xff0c;你知道是哪两种吗&#xff1f; 解法 用 Postman 发送一个 GET 请求&#xff0c;提交一个名为a,值为1的变量。 http://61.147.171.105:65402/?a1用 Postman 发送一个 POST 请求&#xff0c;提交一个名为b,值为…

【吊打面试官系列】Java高并发篇 - 可以直接调用 Thread 类的 run ()方法么?

大家好&#xff0c;我是锋哥。今天分享关于 【可以直接调用 Thread 类的 run ()方法么&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 可以直接调用 Thread 类的 run ()方法么&#xff1f; 当然可以。但是如果我们调用了 Thread 的 run()方法&#xff0c;它的行…

VSCode通过SSH连接虚拟机Ubuntu失败

问题说明 最近使用VSCode通过SSH连接Ubuntu&#xff0c;通过VSCode访问Ubuntu进行项目开发&#xff0c;发现连接失败 在VSCode中进行SSH配置 这些都没有问题&#xff0c;但在进行连接时候出现了问题&#xff0c;如下&#xff1a; 出现了下面这个弹窗 解决方法 发现当…

【c1】数据类型,运算符/循环,数组/指针,结构体,main参数,static/extern,typedef

文章目录 1.数据类型&#xff1a;编译器&#xff08;compiler&#xff09;与解释器&#xff08;interpreter&#xff09;&#xff0c;中文里的汉字和标点符号是两个字节&#xff0c;不能算一个字符&#xff08;单引号&#xff09;2.运算符/循环&#xff1a;sizeof/size_t3.数组…

在.NET架构的Winform项目中引入“异步编程”思想和技术

在.NET架构的Winform项目中引入“异步编程”思想和技术 一、异步编程引入&#xff08;1&#xff09;异步编程引入背景&#xff08;2&#xff09;异步编程程序控制流图&#xff08;3&#xff09;异步编程前置知识&#xff1a; 二、异步编程demo步骤1&#xff1a;步骤2&#xff1…

Kafka源码分析(五) - Server端 - 基于时间轮的延时组件

系列文章目录 Kafka源码分析-目录 一. 背景 Kafka内部涉及大量的"延时"操作&#xff0c;比如收到PRODUCE请求后可为副本等待一个timeout的时间后再响应客户端。 那我们讨论一个问题&#xff1a;Kafka为什么自己实现了一个延时任务组件&#xff0c;而不直接使用ja…

微信个人号开发api接口-视频号矩阵接口-VIdeosApi

友情链接&#xff1a;VIdeosApi 获取用户主页 接口地址&#xff1a; http://api.videosapi.com/finder/v2/api/finder/userPage 入参 { "appId": "{{appid}}", "lastBuffer": "", "toUserName": "v2_060000231003b2…

网络基础-华为VRP基础CLI操作

基本命令模式 华为设备的命令行模式包括用户视图和特权级模式。 用户视图&#xff08;User View&#xff09;&#xff1a;这是用户登录到华为设备时默认进入的模式。在用户视图下&#xff0c;用户可以执行一些基本的查看命令&#xff0c;但不能进行设备配置或管理。提示符通常…

Golang | Leetcode Golang题解之第72题编辑距离

题目&#xff1a; 题解&#xff1a; func minDistance(word1 string, word2 string) int {m, n : len(word1), len(word2)dp : make([][]int, m1)for i : range dp {dp[i] make([]int, n1)}for i : 0; i < m1; i {dp[i][0] i // word1[i] 变成 word2[0], 删掉 word1[i], …

U盘提示“被写保护”无法操作处理怎么办?

今天在使用U盘复制拷贝文件时&#xff0c;U盘出现“U盘被写保护”提示&#xff0c;导致U盘明明有空闲内存却无法复制的情况。这种情况很常见&#xff0c;很多人在插入U盘到电脑后&#xff0c;会出现"U盘被写保护"的提示&#xff0c;导致无法进行删除、保存、复制等操…

Junit 测试中如何对异常进行断言

本文对在 Junit 测试中如何对异常进行断言的几种方法进行说明。 使用 Junit 5 如果你使用 Junit 5 的话&#xff0c;你可以直接使用 assertThrows 方法来对异常进行断言。 代码如下&#xff1a; Exception exception assertThrows(NumberFormatException.class, () -> {n…

pycharm关闭代码补全

pycharm关闭代码补全 文件-设置 编辑器-常规-代码补全-键入时显示建议

pyecharts绘制世界动态轨迹图(v0.5.X与v1.X版本对比)

一、问题引入 pyecharts官网&#xff1a;https://pyecharts.org/#/zh-cn/intro 在使用Geo或者GeoLines绘制动态轨迹图时&#xff0c;如果所选地区是中国的省份或者城市&#xff0c;是能够匹配到对应的经纬度并且正常绘制的&#xff1b;如果所选地区涉及到其他国家或者国外城市&…

监控公司局域网电脑的软件|局域网电脑监控软件哪个好用

想要监控公司局域网电脑&#xff1f;没问题&#xff0c;市面上有一大堆选择等着你&#xff01;每个软件都有它的独门绝技和适用场合&#xff0c;接下来就让我带你看看哪些软件既好用又功能强大吧&#xff01; &#x1f389;OpManager&#xff1a; 这位大佬适合中大型企业&#…

C语言 | Leetcode C语言题解之第73题矩阵置零

题目&#xff1a; 题解&#xff1a; void setZeroes(int** matrix, int matrixSize, int* matrixColSize) {int m matrixSize;int n matrixColSize[0];int flag_col0 false;for (int i 0; i < m; i) {if (!matrix[i][0]) {flag_col0 true;}for (int j 1; j < n; j…

Unity 性能优化之遮挡剔除(Occlusion Culling)(六)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 前言一、遮挡剔除是什么&#xff1f;二、静态遮挡剔除的使用步骤1.标记为遮挡剔除对象2.创建Occlusion Area组件3.烘焙4.Occlusion窗口Bake的参数Smallest Oc…

后台启动HIVE的JDBC连接

后台启动HIVE的JDBC连接 生活就像一杯咖啡&#xff0c;有时苦涩&#xff0c;有时香甜&#xff0c;但都是值得品味的经历。无论遇到什么挑战&#xff0c;记住在每一天的开始&#xff0c;你都有机会给自己倒上一杯清新的力量&#xff0c;为心灵添一抹温暖。勇敢地面对生活的苦与甜…

专家解读 | NIST网络安全框架(1):框架概览

随 着信息技术的快速发展&#xff0c;组织面临着越来越严峻的网络安全挑战。NIST网络安全框架&#xff08;NIST Cybersecurity Framework&#xff0c;CSF&#xff09;是一个灵活的综合性指南&#xff0c;旨在协助各类组织建立、改进和管理网络安全策略&#xff0c;以加强网络安…

计算机网络学习记录Day1

你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github gitee 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我会尽力带来有趣的内容 计算机网络学习记录Day1 本文基于1.1 计算机网络在信息…