判断完全二叉树节点个数
判断方法
- 使用递归
- 找到完全二叉树的总高度(找到左子树树的总高度)
- 从root开始,
- 如果当前节点层数等于树的高度返回1,也就是此节点与其子树的节点一共只有一个
- 如果右子树的左边界的高度与树的总高度相同,那么左子树为满二叉树,返回左子树节点个数+当前节点(1个)+右子树节点数
- 右子树左边界不到整棵树的深度,那么右子树为满二叉树,返回右子树节点个数+当前节点(1个)+左子树节点数
代码
//节点
struct Node {
int value;
Node* parent;
Node* left;
Node* right;
Node(int v = 0): value(v), parent(nullptr), left(nullptr), right(nullptr) {}
};
//销毁二叉树
void destroy_tree(Node* root) {
if (root == nullptr) {
return;
}
destroy_tree(root->left);
destroy_tree(root->right);
delete root;
}
//找到左子树树的总高度
int get_left_level(Node*node, int level) {
while (node != nullptr) {
level++;
node = node->left;
}
return level - 1;
}
//二分搜索
int bs(Node* node, int level, int h) {
//level == height,节点个数为1
if (level == h) {
return 1;
}
//右子树左边界到了整棵树的深度,左子树一定是满的
//返回左子树节点个数+当前节点(1个)+右子树节点数
if (get_left_level(node->right, level + 1) == h) {
return ((1 << (h - level)) + bs(node->right, level + 1, h));
} else {
//右子树左边界不到整棵树的深度
//右子树高度比左子树少一
//返回右子树节点个数+当前节点(1个)+左子树节点数
return ((1 << (h - level - 1)) + bs(node->right, level + 1, h));
}
}
int node_nums(Node* node) {
if (node == nullptr) {
return 0;
}
return bs(node, 1, get_left_level(node, 1));
}
int main(void)
{
//创建一颗满树
Node* head1 = new Node(0);
Node* node11 = new Node(1);
Node* node12 = new Node(2);
Node* node13 = new Node(3);
Node* node14 = new Node(4);
Node* node15 = new Node(5);
head1->left = node11;
head1->right = node12;
node11->left = node13;
node11->right = node14;
node12->left = node15;
std::cout << node_nums(head1) << std::endl;
destroy_tree(head1);
return 0;
}
版权声明:本文为weixin_44048823原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。