数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)

简介: 数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)

题目描述

现给定一系列不同的非负整数键,如果要求构造出一颗完全二叉树,则可以构造唯一的二叉搜索树。输出此二叉搜索树的层序遍历序列。

完全二叉树

有n个节点的二叉树,对树中节点按从上至下、从左到右顺序进行编号,编号为i(1<= i <= n)节点与满二叉树中编号为i节点在二叉树中位置相同。

二叉搜索树

一颗二叉树,可以为空;如果不为空,满足一下性质:

1.非空左子树的所有键值小于其根节点的键值。

2.非空右子树的所有键值大于其根节点的键值。

3.左、右子树都是二叉搜索树

输入示例

每个输入文件包含一个测试用例。

对于每种情况,第一行包含正整数N(≤ 1 0 0 0)。

然后下一行给出了 N个不同的非负整数键。一行中的所有数字都用空格分隔,不大于2000。

Sample Input:

10

1 2 3 4 5 6 7 8 9 0

输出示例

对于每个测试用例,在一行中打印相应的完全二叉搜索树的层序遍历序列。

一行中的所有数字必须用空格分隔,并且行的末尾不能有额外的空格。

Sample Output:

6 3 8 1 5 7 9 0 2 4

数据结构的选择

二叉树可以通过数组和链表来实现,我们现在要先确定一下用哪种数据结构来解决这道题目。


在之前的学习中,我们使用链表来实现二叉树的存储。因为在一些较为极端的情况下,二叉树可能向左或向右倾斜的程度比较大,这个时候使用数组来实现的话就会造成很大的空间浪费。这是从空间的一个角度来考虑的,而在遍历上,数组和链表两种实现方式都是差不多的。


现在看回这道题目,它需要进行的操作:

  • 填写数字(也属于某种遍历)
  • 层序遍历

在遍历的角度上来看,两种方式都差不多,所以不考虑了。

从空间的角度上来看,完全二叉树的情况下,数组是不会浪费空间的,故而还不能下定论。


最后看到遍历的方式,发现是层序遍历,这就意味着,如果使用数组实现,那么直接顺序输出就是其层序遍历的遍历序列;而链表的层序遍历需要借助队列来实现,显然更为复杂一点。


所以,我们选择数组来实现。


核心算法

void solve(int ALeft, int ARight, int TRoot)
{  
   /*  初始调用为 solve(0, N - 1, 0) */
  n = ARight - ALeft + 1;
  if (n == 0)  
    return;
  L = GetLeftLength(n);  /*  计算出n个结点的树其左子树有多少个结点  */
  T[TRoot] = A[ALeft + L];
  LeftTRoot = TRoot * 2 + 1;
  RightTRoot = LeftTRoot + 1;
  solve(ALeft, ALeft + L - 1, LeftTRoot);
  solve(ALeft + L + 1, ARight, RightTRoot);
}

其中A为排序后的序列,我们需要对输入的序列进行排序,才能得到它, ALeft表示序列最左边的位置的下标,ARight则表示序列最右边的位置的下标。


T是我们求的结果树,TRoot就是结果树的根结点。


除了排序之外,还有一步重要的操作:计算左子树的结点个数,只有确定了左子树的结点个数,我们才能确定根结点以及右子树。


计算左子树的规模

思路

如图所示,完全二叉树的完美二叉树的部分可以用 来表示其结点数,H为其中完美二叉树部分的层数。

接下来把剩余的几个结点个数设为X,总结点数设为N,就可以得到一个关系式:

将公式整理成log形式,得:

对于大规模的计算,X对整体的结果影响很小很小,我们把X忽略,故而有:

N是已知的,所以可以根据这个公式求出H;

继而代入 求出X;

现在得到一整棵完全二叉树的结点数了,要怎么求其左子树的结点呢?

一棵完全二叉树的左子树也一定是一棵完全二叉树,所以可以知道其左子树的结点数应为:

你以为,这样就完了吗?

看一下另外一种情况,我们就会发现目前的X还不是最正确的X:

很显然,这里的X已经不在左子树的范畴内了。

正确应该为:

所以我们应该要对X的取值有一定的限制,或者说,X应该要有一定的范围。

可以考虑,当左子树为一棵完美二叉树时,X可以为0,也可以为

X为0的情况:

X为 的情况:

总结

最后,总结一下计算左子树的规模:

第一步是通过公式 求出H;

第二步是通过公式 求出X;

第三步是选出正确的X,

最后一步就是代入 求出我们最终的结果。


end



目录
相关文章
|
2天前
|
算法 搜索推荐 JavaScript
算法学习:快速排序
算法学习:快速排序
8 1
|
2天前
|
机器学习/深度学习 存储 算法
算法学习:递归
算法学习:递归
11 0
|
2天前
|
存储 算法 Go
算法学习:数组 vs 链表
算法学习:数组 vs 链表
7 0
|
2天前
|
算法 JavaScript 前端开发
算法学习:二分查找
算法学习:二分查找
11 0
|
5天前
|
算法 JavaScript 决策智能
基于禁忌搜索算法的TSP路径规划matlab仿真
**摘要:** 使用禁忌搜索算法解决旅行商问题(TSP),在MATLAB2022a中实现路径规划,显示优化曲线与路线图。TSP寻找最短城市访问路径,算法通过避免局部最优,利用禁忌列表不断调整顺序。关键步骤包括初始路径选择、邻域搜索、解评估、选择及禁忌列表更新。过程示意图展示搜索效果。
|
5天前
|
机器学习/深度学习 算法
基于BP神经网络和小波变换特征提取的烟草香型分类算法matlab仿真,分为浓香型,清香型和中间香型
```markdown 探索烟草香型分类:使用Matlab2022a中的BP神经网络结合小波变换。小波分析揭示香气成分的局部特征,降低维度,PCA等用于特征选择。BP网络随后处理这些特征,以区分浓香、清香和中间香型。 ```
|
6天前
|
机器学习/深度学习 算法
m基于PSO-GRU粒子群优化长门控循环单元网络的电力负荷数据预测算法matlab仿真
摘要: 在MATLAB 2022a中,对比了电力负荷预测算法优化前后的效果。优化前为&quot;Ttttttt111222&quot;,优化后为&quot;Tttttttt333444&quot;,明显改进体现为&quot;Tttttttttt5555&quot;。该算法结合了粒子群优化(PSO)和长门控循环单元(GRU)网络,利用PSO优化GRU的超参数,提升预测准确性和稳定性。PSO模仿鸟群行为寻找最优解,而GRU通过更新门和重置门处理长期依赖问题。核心MATLAB程序展示了训练和预测过程,包括使用&#39;adam&#39;优化器和超参数调整,最终评估并保存预测结果。
15 0
|
7天前
|
算法 安全
基于龙格库塔算法的SIR病毒扩散预测matlab仿真
该程序使用龙格库塔算法实现SIR模型预测病毒扩散,输出易感、感染和康复人群曲线。在MATLAB2022a中运行显示预测结果。核心代码设置时间区间、参数,并定义微分方程组,通过Runge-Kutta方法求解。SIR模型描述三类人群动态变化,常微分方程组刻画相互转化。模型用于预测疫情趋势,支持公共卫生决策,但也存在局限性,如忽略空间结构和人口异质性。
|
7天前
|
机器学习/深度学习 监控 算法
基于yolov2深度学习网络的昆虫检测算法matlab仿真,并输出昆虫数量和大小判决
YOLOv2算法应用于昆虫检测,提供实时高效的方法识别和定位图像中的昆虫,提升检测精度。核心是统一检测网络,预测边界框和类别概率。通过预测框尺寸估算昆虫大小,适用于农业监控、生态研究等领域。在matlab2022A上运行,经过关键升级,如采用更优网络结构和损失函数,保证速度与精度。持续优化可增强对不同昆虫的检测能力。![image.png](https://ucc.alicdn.com/pic/developer-ecology/3tnl7rfrqv6tw_e760ff6682a3420cb4e24d1e48b10a2e.png)
|
8天前
|
算法 调度 决策智能
基于自适应遗传算法的车间调度matlab仿真,可以任意调整工件数和机器数,输出甘特图
这是一个使用MATLAB2022a实现的自适应遗传算法解决车间调度问题的程序,能调整工件数和机器数,输出甘特图和适应度收敛曲线。程序通过编码初始化、适应度函数、遗传操作(选择、交叉、变异)及自适应机制进行优化,目标如最小化完工时间。算法在迭代过程中动态调整参数,以提升搜索效率和全局优化。

热门文章

最新文章