数据结构学习记录——树习题-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



目录
相关文章
为什么要学习数据结构与算法
今天,我向大家介绍一门非常重要的课程——《数据结构与算法》。这门课不仅是计算机学科的核心,更是每一位开发者从“小白”迈向“高手”的必经之路。
为什么要学习数据结构与算法
|
4月前
|
算法系列之数据结构-二叉树
树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
98 9
 算法系列之数据结构-二叉树
|
4月前
|
算法系列之数据结构-Huffman树
Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
117 3
 算法系列之数据结构-Huffman树
|
4月前
|
算法系列之数据结构-二叉搜索树
二叉查找树(Binary Search Tree,简称BST)是一种常用的数据结构,它能够高效地进行查找、插入和删除操作。二叉查找树的特点是,对于树中的每个节点,其左子树中的所有节点都小于该节点,而右子树中的所有节点都大于该节点。
107 22
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
139 29
C 408—《数据结构》算法题基础篇—链表(上)
408考研——《数据结构》算法题基础篇之链表(上)。
195 25
C 408—《数据结构》算法题基础篇—数组(通俗易懂)
408考研——《数据结构》算法题基础篇之数组。(408算法题的入门)
176 23
架构学习:7种负载均衡算法策略
四层负载均衡包括数据链路层、网络层和应用层负载均衡。数据链路层通过修改MAC地址转发帧;网络层通过改变IP地址实现数据包转发;应用层有多种策略,如轮循、权重轮循、随机、权重随机、一致性哈希、响应速度和最少连接数均衡,确保请求合理分配到服务器,提升性能与稳定性。
1054 11
架构学习:7种负载均衡算法策略
探索局域网电脑监控软件:Python算法与数据结构的巧妙结合
在数字化时代,局域网电脑监控软件成为企业管理和IT运维的重要工具,确保数据安全和网络稳定。本文探讨其背后的关键技术——Python中的算法与数据结构,如字典用于高效存储设备信息,以及数据收集、异常检测和聚合算法提升监控效率。通过Python代码示例,展示了如何实现基本监控功能,帮助读者理解其工作原理并激发技术兴趣。
159 20
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
202 2

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问