目录
一,完全二叉树
一棵有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。
完全二叉树是Full Binary Tree中的一种特例,而Perfect Binary Tree又是完全二叉树中的一种特例。
FBT、PBT 满二叉树、Full Binary Tree、Perfect Binary Tree_full binary tree perfect binary tree-CSDN博客
二,完全二叉树的性质
除根节点外,节点n的父节点是节点n/2
三,OJ实战
CSU 1946 A Rational Sequence
Description
An infinite full binary tree labeled by positive rational numbers is defined by:
The label of the root is 1/1.
The left child of label p/q is p/(p+q).
The right child of label p/q is (p+q)/q.
The top of the tree is shown in the following figure:
A rational sequence is defined by doing a level order (breadth first) traversal of the tree (indicated by the light dashed line). So that:
Write a program to compute the nth element of the sequence, F(n). Does this problem sound familiar? Well it should! But we changed it a little!
Input
The first line of input contains a single integer P, (1 <= P <= 1000), which is the number of data sets that follow. Each data set should be processed identically and independently.
Each data set consists of a single line of input. It contains the data set number, K, and the index, N, of the sequence element to compute (1 <= N <= 2147483647).
Output
For each data set there is a single line of output. It contains the data set number, K, followed by a single space which is then followed by the numerator of the fraction, followed immediately by a forward slash (‘/’) followed immediately by the denominator of the fraction. Inputs will be chosen so neither the numerator nor the denominator will overflow an 32-bit unsigned integer.
Sample Input
4
1 1
2 4
3 11
4 1431655765
Sample Output
1 1/1
2 1/3
3 5/2
4 2178309/1346269
这是完全二叉树,所以可以直接找到每个节点的父亲是谁,递归即可解决本题。
代码:
#include<iostream>
using namespace std;
int a, b;
void f(int n)
{
if (n == 1)
{
a = 1, b = 1;
return;
}
f(n / 2);
if (n % 2)a += b;
else b += a;
}
int main()
{
int p, n;
cin >> p;
while (p--)
{
cin >> n;
cout << n<<' ';
cin >> n;
f(n);
cout << a << '/' << b << endl;
}
return 0;
}
CSU 1213 二叉树结点公共祖先
题目:
Description
一个顺序存储的完全二叉树:
1
/ \
2 3
/ \ / \
4 5 6 7
...
任意给定两结点的编号,求两结点最近的公共祖先。
Input
每组数据一行,为空格隔开的两个数i和j,皆为32位有符号正整数
Output
每组数据对应一行,为编号为i和j的结点的最近公共祖先的编号
Sample Input
4 5
4 7
Sample Output
2
1
这是完全二叉树,代码:
#include<iostream>
using namespace std;
int main()
{
int a,b;
while(cin>>a>>b)
{
while(a!=b)
{
if(a>b)a/=2;
else b/=2;
}
cout<<a<<endl;
}
return 0;
}
力扣 222. 完全二叉树的节点个数
题目:
给出一个完全二叉树,求出该树的节点个数。
说明:
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
示例:
输入:
1
/ \
2 3
/ \ /
4 5 6
输出: 6
代码:
class Solution {
public:
int countNodes(TreeNode* root) {
if (!root)return 0;
return countNodes(root->left) + countNodes(root->right) + 1;
}
};
力扣 919. 完全二叉树插入器
完全二叉树 是每一层(除最后一层外)都是完全填充(即,节点数达到最大)的,并且所有的节点都尽可能地集中在左侧。
设计一种算法,将一个新节点插入到一个完整的二叉树中,并在插入后保持其完整。
实现 CBTInserter
类:
CBTInserter(TreeNode root)
使用头节点为root
的给定树初始化该数据结构;CBTInserter.insert(int v)
向树中插入一个值为Node.val == val
的新节点TreeNode
。使树保持完全二叉树的状态,并返回插入节点TreeNode
的父节点的值;CBTInserter.get_root()
将返回树的头节点。
示例 1:
输入 ["CBTInserter", "insert", "insert", "get_root"] [[[1, 2]], [3], [4], []] 输出 [null, 1, 2, [1, 2, 3, 4]] 解释 CBTInserter cBTInserter = new CBTInserter([1, 2]); cBTInserter.insert(3); // 返回 1 cBTInserter.insert(4); // 返回 2 cBTInserter.get_root(); // 返回 [1, 2, 3, 4]
提示:
- 树中节点数量范围为
[1, 1000]
0 <= Node.val <= 5000
root
是完全二叉树0 <= val <= 5000
- 每个测试用例最多调用
insert
和get_root
操作104
次
class CBTInserter {
public:
CBTInserter(TreeNode* root) {
this->root=root;
num=CountNodes(root);
}
int insert(int val) {
int len = GetBitLength(++num);
auto p = root;
for(int i=len-2;i;i--){
if(num&(1<<i))p=p->right;
else p=p->left;
}
if(num&1)p->right=new TreeNode(val);
else p->left=new TreeNode(val);
return p->val;
}
TreeNode* get_root() {
return root;
}
TreeNode* root;
int num;
};