1.题目
一棵完全二叉树的节点总数
题意:已知一棵完全二叉树,求其节点的个数
要求:时间复杂度低于O(N),N为这棵树的节点个数。
公式节点个数=2^n-1
2.思路
低于O(N) 那么我们不可能用层序遍历去求解
我们可以用满二叉树的计算公式去求解
求解完全二叉树的深度
int GetLeftHeight(NODE *Head, int Level)
{
while(NULL != Head)
{
Level++;
Head = Head->Left;
}
return Level - 1;
}
我们知道一颗完全二叉树的深度 等于他最左节点的深度
如果当前节点的右子树的最左节点不是空,那么这个节点的左子树一定是满二叉树,右子树是完全二叉树递归求解
如果当前节点的右子树的最左节点是空,那么右子树一定是满二叉树,左子树是完全二叉树,递归求解
3.代码
int CB(NODE *Head, int Level, int TotalHeight)
{
//递归出口 当当前的层数和总层数相同
if(Level == TotalHeight)
return 1;
//如果右子树上的高度 == 左子树的高度 那么左子树就是一个满二叉树
//2^n - 1 + 1(根) 那么右子树就是一颗完全二叉树 递归求解
if(GetLeftHeight(Head->Right, Level+1) == TotalHeight)
return (1<< (TotalHeight-Level)) +
CB(Head->Right, Level+1, TotalHeight);
//如果不是 那么右子树 肯定是一个满二叉树 左子树是一个完全二叉树
//递归求解 右子树比左子树 少一层
else
return (1<< (TotalHeight-Level-1)) +
CB(Head->Right, Level+1, TotalHeight);
}
int CountB(NODE *Head)
{
if(NULL == Head)
return 0;
return CB(Head, 1, GetLeftHeight(Head, 1));
}
int main(int argc, char** argv)
{
string Str = "1_2_4_#_#_5_#_#_3_6_#_#_7_#_#_";
queue<string> Queue;
split (Str, Queue);
NODE *Head = ReconPreOrder(Queue);
//PreOrder(Head);
//InOrder(Head);
//PosOrder(Head);
string Str1 = "1_2_#_#_3_4_#_#_5_#_#_";
split (Str1, Queue);
NODE *Head1 = ReconPreOrder(Queue);
if(IsComplete(Head))
{
cout<<"是一个完全二叉树 ";
cout<<"节点个数为 "<<CountB(Head)<<endl;
}
else
{
cout<<"不是一个完全二叉树"<<endl;
}
if(IsComplete(Head1))
{
cout<<"是一个完全二叉树 ";
cout<<"节点个数为 "<<CountB(Head1)<<endl;
}
else
{
cout<<"不是一个完全二叉树"<<endl;
}
return 0;
}