数据结构第四天: Complete Binary Search Tree 【搜索二叉树,完全二叉树】

news/2025/3/5 9:23:13/

二叉搜索树 bst 被递归地定义为具有以下属性的二叉树节点的左子树仅包含键小于节点键的节点
a 的右子树节点只包含键大于或等于节点键的节点
左右子树也必须是二叉搜索树
完全二叉树cbt是一棵完全充满可能异常的树从左到右填充的底层现在给定一系列不同的非负整数键,如果要求树也必须是你认为的cbt,则可以构造一个唯一的bst输出此 bst 的层序遍历序列输入规范
每个输入文件包含一个测试用例,每个案例第一行包含一个正整数 n ≤ 1000 然后 n 个不同的非负整数keys在下一行给出,一行中的所有数字用空格分隔,并且不大于2000输出规范

 这道题需要的操作时排序并且需要遍历,最重要的一点它是个完全二叉树,所以数组是最适合的

这道题我的思路来自于浙江大学课件7.0.2完全二叉树

解题思路 

这道题说白就是将输入的样例构造成一个完全搜索二叉树。因为完全线索二叉树的根节点一定是是一个处于左右子树中间的那个值(搜索二叉树其根节点要比自己的左子树上所有节点都大又要比自己右子树上所有节点都小)然后我们的思路就是在排好序的样例上每次去找一下当前函数所在的树的根节点然后将其插入二叉搜索树对应的位置,然后直接输出即可,因为此时我们构建的树数组只要我们顺序遍历就是层序遍历。

int n;cin>>n;for(int i=0;i<n;i++){int a;cin>>a;tree[i] = a;}//对输入样例排序sort(tree,tree+n,compare);solve(0,n-1,0);for(int i=0;i<n-1;i++)cout<<Ttree[i]<<" ";cout<<Ttree[n-1];

那么solve函数(排好序的样例上每次去找一下当前函数所在的树的根节点然后将其插入二叉搜索树对应的位置)该咋写呢?我们的思路是这样的,我们入函数的一定是所有样例,那么我们就是找整个样例的根节点,我们又知道根节点一定是是一个处于左右子树中间的那个值,然后我们的数组又是从0开始存值的,所以说其实在样例数组中左子树的个数加上此时这个树的左边界就可以确定此时这个树的根节点的值在样例数组的位置。

//得出左边节点个数int L = GetLeftLength(n);//左子树的个数就是此根节点的下标Ttree[rootIndex] = tree[L + Aleft];

然后我们找到最大的树的根节点,我们就可以继续递归去找它的左子树和右子树的根节点。这样这个函数该解决的问题就解决了。

//此节点的左节点在完全二叉树的下标int leftRootIndex = rootIndex * 2 + 1;//此节点的右节点在完全二叉树的下标int rightRootIndex = leftRootIndex + 1;solve(Aleft,Aleft+L-1,leftRootIndex);solve(Aleft+L+1,Aright,rightRootIndex);

但是如何找每个树的左子树的个数呢?

我们可以根据上图推出一个完全二叉树完美的那部分总共的个数(N)为pow(2,这个树的高度)-1+这个树减去完美部分的节点个数(X),

 

 然后我们就可以通过上述的公式推出 树的高度(h)=log2(N+1-X) ,然后我们就可以通过这个算出X,(但是我们题目中需要算出的是左子树节点个数如下图是不满足L(左子树个数)=pow(2,h-1)-1+X1(左子树除了完美部分之外的个数)这个公式的,因为很可能右边也有节点)

(像这样的情况就不满足)

所以X1=min(X,左子树最大值(pow(2,h-1)))

然后就可以根据公式L(左子树个数)=pow(2,h-1)-1+X1写出函数。

int GetLeftLength(int n){//将完全二叉树完美的部分的高度求出,由2的h次方 -1 +x = n推出int h = log2(n+1);//求出左边除去完满二叉树部分多余的节点int x = n - pow(2,h) + 1;int a = pow(2,h-1);x = min(x,a);//多余的节点 + 完美二叉树左边一边的节点int L = a - 1 + x;return L;
}

下面是完整代码 

#include <iostream>
#include <cmath>
#include <algorithm>using namespace std;
int compare(int a, int b){return a<b;
}
int tree[1001];
int Ttree[1001];
int GetLeftLength(int n){//将完全二叉树完美的部分的高度求出,由2的h次方 -1 +x = n推出int h = log2(n+1);//求出左边除去完满二叉树部分多余的节点int x = n - pow(2,h) + 1;int a = pow(2,h-1);x = min(x,a);//多余的节点 + 完美二叉树左边一边的节点int L = a - 1 + x;return L;
}
//后面的参数都是每次遍历时此时的树
//:Aleft:输入样例左边界,Aright:输入样例右边界,完全二叉树根节点下标
void solve(int Aleft,int Aright,int rootIndex){int n = Aright - Aleft + 1;// cout<<n<<endl;if(n==0) return;//得出左边节点个数int L = GetLeftLength(n);//左子树的个数就是此根节点的下标Ttree[rootIndex] = tree[L + Aleft];//此节点的左节点在完全二叉树的下标int leftRootIndex = rootIndex * 2 + 1;//此节点的右节点在完全二叉树的下标int rightRootIndex = leftRootIndex + 1;solve(Aleft,Aleft+L-1,leftRootIndex);solve(Aleft+L+1,Aright,rightRootIndex);
}
int main(){int n;cin>>n;for(int i=0;i<n;i++){int a;cin>>a;tree[i] = a;}//对输入样例排序sort(tree,tree+n,compare);solve(0,n-1,0);for(int i=0;i<n-1;i++)cout<<Ttree[i]<<" ";cout<<Ttree[n-1];return 0;
}

http://www.ppmy.cn/news/82364.html

相关文章

墨云科技 web漏洞研究岗一面复盘

墨云科技 web漏洞研究岗一面复盘 1.xss的分类说一下2.xss怎么防御的3.详细讲讲什么是DOM,越详细越好4.反射型XSS和DOM型XSS的区别5.富文本XSS了解过吗,说一下6.你能讲讲JNDI注入吗?比如JNDI注入的原理7.JNDI注入除了ldap协议还了解什么其他的协议?8.JNDI注入除了加载远程文…

Cisco Secure Web Appliance Virtual 15.0 发布 - 适用于网络安全的思科高级威胁防护

Cisco Secure Web Appliance Virtual, AsyncOS for WSA 15.0.0 LD 请访问原文链接&#xff1a;https://sysin.org/blog/cisco-secure-web-appliance-15/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Cisco Secure Web Appli…

最小二乘法求导-公式推导

多元线性回归模型 1. 建立模型&#xff1a;模型函数 Y ^ W T X \hat{Y} W^TX Y^WTX 如果有 n1 条数据&#xff0c;每条数据有 m1 种x因素&#xff08;每种x因素都对应 1 个权重w&#xff09;&#xff0c;则 &#x1f449;已知数据&#xff1a;实际Y值 [ y 0 y 1 y 2 y 3 . …

HTML小结

HTML 超文本标记语言&#xff08;Hypertext Markup Language&#xff09;,是用来开发网页结构和内容的技术。 通过各类标签标记想要显示的网页的各个部分&#xff0c;然后浏览器再通过HTML标准&#xff0c;把标签转换为网页内容。超文本指的是网页可以包含图片、链接、音乐、视…

ELK企业级日志分析系统

ELK概述 为什么要使用 ELK 日志主要包括系统日志、应用程序日志和安全日志。系统运维和开发人员可以通过日志了解服务器软硬件信息、检查配置过程中的错误及错误发生的原因。经常分析日志可以了解服务器的负荷&#xff0c;性能安全性&#xff0c;从而及时采取措施纠正错误。 …

ELK 企业级日志分析系统

---------------------- ELK 概述 ---------------------------------------- 1、ELK 简介 ELK平台是一套完整的日志集中处理解决方案&#xff0c;将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用&#xff0c; 完成更强大的用户对日志的查询、排序、统计需求。 ●…

vue2和vue3的区别

1.vue2vue3响应式原理不同 2.vue3支持碎片&#xff0c;vue不支持 3.vue3是组合式API,vue2是选项式API 4.v-if和v-for的优先级不同 5.生命周期不同 6.diff算法不同 7.vue3新增Teleport传送门组件、 1&#xff0c;vue2 vue3 响应式原理不同 vue2 的双向数据绑定是利用 ES5 的一个…

功能上新|内存篇:PSS显存、内存占用、堆内存对象快照

内存管理一直是游戏研发的重中之重&#xff0c;当项目运行时的内存压力较大时&#xff0c;更容易达到设备阈值引起闪退。近年来&#xff0c;当出海成为许多游戏公司新选择的同时&#xff0c;我们也发现海外设备对项目的内存情况有着更严格的要求。 为了帮助开发者更全面地了解…