分析:
完全二叉树特点:完全二叉树的倒数第二层一定全部都是满的
步骤
1、先求出这颗树的高度
2、在求根结点的右子树的高度(找根结点右子树的最左结点)
3、这样就会出现两种情况,一种是左子树的高度和右子树的高度相等,则说明左子树是满二叉树,可用公式求出,再把这个节点的右孩子节点当做根结点进行递归就可以求出整个树的结点数;第二种是右子树的高度比左子树小1,这个时候巧了,右子树也是一满二叉树,只不过比左子树的高度小1而已,也通过递归来实现
这样就通过类似二分的方法来求出树的结点数
代码:
Tree.h
#pragma once
#include <vector>
#include <math.h>
template<class T>
struct Node
{
T _data;
Node<T>* _left;
Node<T>* _right;
Node(const T& x=T())
:_left(NULL)
, _right(NULL)
, _data(x)
{}
};
template<class T>
class CompleteBinaryTree
{
typedef Node<T> Node;
public:
CompleteBinaryTree()
{}
CompleteBinaryTree(T *arr,size_t size)
{
int index = 0;
_root = CreateTree(index , arr, size);
}
public:
//求完全二叉树的节点数
size_t Count()
{
size_t count = 0;
int hight = Hight();/先求出这颗完全二叉树的高度
return _Count(_root,count,hight);
}
size_t Hight()
{
return SubHight(_root);
}
size_t SubHight(Node* root)
{
size_t hight = 0;
while (root){
++hight;
root = root->_left;
}
return hight;
}
protected:
//根据先序序列,建好的树不一定是完全二叉树,测试的时候给的是完全二叉树
Node* CreateTree(int& i,T* arr,size_t size)
{
while (i < size){
if (arr[i] == '#')
return NULL;
Node* root = new Node(arr[i]);
root->_left = CreateTree(++i, arr, size);
root->_right = CreateTree(++i, arr, size);
return root;
}
return NULL;
}
size_t _Count(Node* root, size_t& size, size_t hight)
{
size_t count = 0;
if (root){
size_t subrighthight = SubHight(root->_right);
if (subrighthight == hight - 1){//左子树是满二叉树
size += pow(2.0, (hight - 1)) - 1 + 1;
size += _Count(root->_right, count, --hight);
}
else{
size += pow(2.0, (hight - 2)) - 1 + 1;
size += _Count(root->_left, count, --hight);
}
}
return size;
}
protected:
Node* _root;
};
Test.cpp
#include <iostream>
#include "Tree.h"
using namespace std;
void Test()
{
int arr1[11] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, '#', '#'};
CompleteBinaryTree<int> cbt1(arr1,sizeof(arr1)/sizeof(arr1[0]));
std::cout << cbt1.Count() << std::endl;
int arr2[21] = { 1, 2, 3, 4, '#', '#', 5, '#', '#', 6, 7, '#', '#' ,'#', 8, 9, '#', '#', 10, '#', '#'};
CompleteBinaryTree<int> cbt2(arr,sizeof(arr2)/sizeof(arr2[0]));
std::cout << cbt2.Count() << std::endl;
}
int main()
{
Test();
system("pause");
return 0;
}
测试结果:
输出 5
10
《完》
转载于:https://blog.51cto.com/lingdandan/1834550